Laravel Eloquent 三表带where条件统计商品总数量如何实现
实现方案
关于是否需要使用hasManyThrough关联
hasManyThrough不是必选项,你可以根据业务场景选择:如果仅需要统计生产数量,直接用join关联查询的方式更高效直观;如果需要同时获取商品关联的所有生产批次信息,定义hasManyThrough会更方便后续关联操作。
前置模型关联定义(可选,根据你选择的实现方式配置)
首先给出各个模型的基础关联定义:
- Item模型(app/Models/Item.php)
// 关联生产明细 public function details() { return $this->hasMany(Detail::class, 'item_id'); } // 可选:hasManyThrough关联到生产批次 public function productions() { return $this->hasManyThrough( Production::class, Detail::class, 'item_id', // Detail表关联Item的外键 'id', // Production表的主键 'id', // Item表的主键 'production_id' // Detail表关联Production的外键 ); }
- Detail模型(app/Models/Detail.php)
// 关联生产批次 public function production() { return $this->belongsTo(Production::class, 'production_id'); } // 关联商品 public function item() { return $this->belongsTo(Item::class, 'item_id'); }
- Production模型(app/Models/Production.php)
// 关联生产明细 public function details() { return $this->hasMany(Detail::class, 'production_id'); }
实现代码(推荐直接join方式,性能最优)
// 替换为你实际的起止日期 $startDate = '2024-01-01'; $endDate = '2024-06-30'; $itemProductionStats = Item::selectRaw('items.name, SUM(details.qty) as total_production_qty') ->join('details', 'items.id', '=', 'details.item_id') ->join('productions', 'details.production_id', '=', 'productions.id') ->whereBetween('productions.date', [$startDate, $endDate]) ->groupBy('items.id', 'items.name') ->get(); // 遍历输出结果示例 foreach ($itemProductionStats as $stat) { echo $stat->name . ': ' . $stat->total_production_qty; }
基于关联的写法(如果你不想直接写join)
如果你已经定义了Detail和Production的关联,也可以用whereHas实现,可读性更高:
$itemProductionStats = Item::selectRaw('items.name, SUM(details.qty) as total_production_qty') ->join('details', 'items.id', '=', 'details.item_id') ->whereHas('details.production', function ($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }) ->groupBy('items.id', 'items.name') ->get();
内容的提问来源于stack exchange,提问作者Mulyono T
相关产品推荐
相关产品推荐

