如何基于item_id统计quantity总和?Laravel关联查询代码结果异常
问题:基于item_id计算quantity总和结果错误,仅返回单条数据值
我需要基于item_id计算tableThreeItems表中对应quantity的总和,表中存在相同item_id的两条数据,quantity分别为4和40,预期结果为44,但当前代码始终返回4。
模型关联代码
// TableOne.php public function tableTwoItems() { return $this->hasMany(TableTwoItems::class); } // TableTwoItem.php public function tableOne() { return $this->belongsTo(TableOne::class); } public function tableThreeItems(){ return $this->hasMany(TableThreeItem::class); } // TableThreeItem.php public function tableTwoItem() { return $this->belongsTo(TableTwoItem::class); }
业务代码
public static function getItemSumForProcessing(int $itemId): int { $tableRelationship = 'tableTwoItems.tableThreeItems'; $item = self::with([$tableRelationship]) ->where('status_id', Statuses::FOR_APPROVAL) ->whereHas($tableRelationship, function ($query) use ($itemId) { $query->where('item_id', $itemId); }) ->first(); if (!$item) { return 0; } $total = $item->tableTwoItems->flatMap(function ($item) use ($itemId) { return $item->tableThreeItems->where('item_id', $itemId); }); return $total->sum('quantity'); }
问题原因
当前代码使用first()方法仅获取了第一条符合条件的TableOne记录,后续仅计算了这条记录关联的tableThreeItems数据总和。而另一条quantity=40的数据属于其他TableOne或TableTwoItem记录,未被纳入计算范围,因此结果仅返回单条数据的数值。
解决方案
方案1:数据库层面直接聚合(推荐,性能更优)
直接通过关联筛选在数据库完成求和,无需加载所有模型实例:
public static function getItemSumForProcessing(int $itemId): int { return TableThreeItem::whereHas('tableTwoItem.tableOne', function ($query) { $query->where('status_id', Statuses::FOR_APPROVAL); }) ->where('item_id', $itemId) ->sum('quantity'); }
方案2:修改原有逻辑查询所有符合条件的记录
如果需要保留原有模型加载逻辑,将first()替换为get(),遍历所有记录计算总和:
public static function getItemSumForProcessing(int $itemId): int { $tableRelationship = 'tableTwoItems.tableThreeItems'; $items = self::with([$tableRelationship]) ->where('status_id', Statuses::FOR_APPROVAL) ->whereHas($tableRelationship, function ($query) use ($itemId) { $query->where('item_id', $itemId); }) ->get(); if ($items->isEmpty()) { return 0; } $total = $items->flatMap(function ($oneItem) use ($itemId) { return $oneItem->tableTwoItems->flatMap(function ($twoItem) use ($itemId) { return $twoItem->tableThreeItems->where('item_id', $itemId); }); }); return $total->sum('quantity'); }
内容的提问来源于stack exchange,提问作者user19991216
相关产品推荐
相关产品推荐

