You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:09:03