【问题标题】:Laravel Eloquent group results by relationLaravel Eloquent 组的关系结果
【发布时间】:2021-01-26 22:59:47
【问题描述】:

我正在努力让 Laravel Eloquent 以我想要的方式检索和分组结果。

基本上,我正在创建一个“我的议程”页面,该页面按截止日期的顺序显示所有任务,但如果 2 个或更多任务(按顺序)属于同一阶段,并且如果 2 个或更多阶段属于同一阶段,则将它们分组在一起到同一个项目。

我的数据是项目 ->(有很多)阶段 ->(有很多)任务

我想按如下方式输出我的数据:

Project B
    Stage 2
        Task 1 (due 1st Sep)
        Task 3 (due 2nd Sep)
    Stage 1
        Task 2 (due 3rd Sep)

Project A
    Stage 1
        Task 2 (due 4th Sep)

Project B <---- repeated as Project A has a stage->task due before these tasks due
    Stage 3
       Task 2 (due 5th Sep)


Project A  <---- repeated as Project B has a stage->task due before
    Stage 1 <---- repeated
        Task 1 (due 6th Sep)

有什么想法可以实现吗?我愿意在前端使用 JS/Vue/Lodash 执行此操作。

提前致谢!

M

【问题讨论】:

  • 你不能用关系做这个,你必须先用leftjoin然后用groupby
  • 有什么想法或资源可以帮助我解决这个问题吗?谢谢。

标签: laravel eloquent one-to-many eloquent-relationship


【解决方案1】:

我认为你可以这样做:

首先,让我们用 JOIN 合并所有表。如果你想查看所有没有任何关系数据的项目和阶段,你可以使用 LEFT JOIN,或者 RIGHT JOIN,我不知道哪个会起作用。

$tasks = Task::orderBy("due")
  ->join("stages", "stages.id", "=", task.stage_id)
  ->join("projects", "projects.id", "=", stages.project_id)
  ->select("pick the columns you want to have")
  ->get();

我认为你应该将这种类型的数组作为你的输出,这样你就不会因为重复的键名而遇到任何问题。

/*
$output = [
  [
    'project'=> A,
    'stages'=> [
       stage_name => [task 1, task 2],
       stage_name => [task 4, task 8],
    ],
  ],
  [
    'project'=> B,
    'stages'=> [
       stage_name => [task 5],
    ],
  ],
  [...]
];
*/

要创建这种类型的数组,下面的函数应该可以工作。

$output = [];

foreach($tasks => $task) {
   $project = $task['project_name'];
   $lastEntry = $output[count($output) - 1];
   if ( count($output) > 0 && $lastEntry['project'] == $project) {
      // this means $task should be inserted in the last array.
      // You should check for stages.
      if (array_key_exists($task['stage_name'], $lastEntry['stages'])) {
        $lastEntry['stages'][$task['stage_name']][] = $task;  
      } else {
        $lastEntry['stages'][$task['stage_name']] = [$task];
      }
      // I think $lastEntry['stages'][$task['stage_name']][] = $task; will work without checking stage names, but I can't be sure, you need to try it.
   } else {
      // This means you should create a new item in $output.
      $output[] = [
        'project' => name,
        'stages' => [
          'stage_name' => [$task];
        ]
      ]
   }
}

我直接在这里创建了这些代码。可能有错别字和一切,但逻辑应该有效。

【讨论】:

  • 行得通!不得不稍微编辑它,但它引导我朝着正确的方向前进!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 2016-07-27
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 2016-06-15
相关资源
最近更新 更多