Laravel如何根据courseId为数组对应项新增查询得到的points字段
问题原因
- 核心逻辑错误:每次foreach循环时调用
array_map遍历整个$response数组,将所有子项的points字段统一赋值为当前循环对应课程的积分值,导致所有子项的积分最终被覆盖为最后一次循环的查询结果 - 冗余语法:查询单条课程ID的积分总和时,不需要添加
groupBy('courseId')条件,where已经过滤出了当前课程的所有数据,sum方法可以直接统计对应总和
修复代码
最简修改方案(直接修改原数组)
foreach ($response as &$item) { $item['points'] = DB::table('student_learning') ->where('courseId', $item['courseId']) ->sum('points'); } // 销毁引用避免后续操作出现异常 unset($item); // 输出结果 dump($response);
不修改原数组生成新结果集
$res = []; foreach ($response as $item) { $currentPoints = DB::table('student_learning') ->where('courseId', $item['courseId']) ->sum('points'); $item['points'] = $currentPoints; $res[] = $item; } // 输出结果 dump($res);
性能优化方案(避免N+1查询问题,适合课程数量多的场景)
如果$response中的课程数量较多,循环内单次查询会产生大量数据库请求,可以批量查询所有课程的积分后统一赋值:
// 提取所有课程ID $courseIds = array_column($response, 'courseId'); // 批量查询所有课程的积分总和,返回以courseId为键、积分为值的数组 $pointsMap = DB::table('student_learning') ->whereIn('courseId', $courseIds) ->groupBy('courseId') ->pluck(DB::raw('sum(points)'), 'courseId') ->toArray(); // 遍历赋值 foreach ($response as &$item) { // 没有对应积分时默认赋值0 $item['points'] = $pointsMap[$item['courseId']] ?? 0; } unset($item); dump($response);
内容的提问来源于stack exchange,提问作者user17189691
相关产品推荐
相关产品推荐

