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

Laravel Eloquent关联查询SUM求和列未出现在结果集如何解决

问题原因

你之前的两种写法都无法拿到聚合字段的核心原因:

  • whereHas本质是生成EXISTS子查询,仅用于判断关联是否存在,子查询内定义的SELECT字段不会被主查询返回
  • 深层关联with预加载的闭包仅用于过滤关联数据,直接在子关联中写SUM聚合只会作用于明细层级,不会自动汇总到供应商主模型上

解决方案

方案1:SQL层面直接聚合(推荐,性能最优,适配大数据量)

直接通过子查询将汇总结果加到主查询字段中,执行效率最高,返回的模型直接挂载聚合字段:

$collectionCenters = Supplier::where('supplier_type', 'juridic_person')
    // 可选:如果需要过滤掉没有符合条件采购记录的供应商,保留这行
    ->whereHas('purchases.details', fn($q) => $q->where('unit', 'kg'))
    ->selectRaw('suppliers.*, (
        SELECT SUM(pd.qty)
        FROM purchase_details pd
        INNER JOIN purchases p ON pd.purchase_id = p.id
        WHERE p.supplier_id = suppliers.id AND pd.unit = "kg"
    ) as purchasesQtyKg')
    ->get();

查询完成后直接通过$supplier->purchasesQtyKg即可获取对应汇总值。
如果使用Laravel 8及以上版本,也可以用自带的withAggregate方法简化写法:

$collectionCenters = Supplier::where('supplier_type', 'juridic_person')
    ->whereHas('purchases.details', fn($q) => $q->where('unit', 'kg'))
    ->withAggregate(
        'purchases.details', 
        'SUM(qty)',
        fn($q) => $q->where('unit', 'kg')
    )
    ->get();

此时聚合字段默认名为purchases_details_sum_qty,可以直接调用。

方案2:集合层汇总(适合小数据量场景)

如果你的供应商数据量不大,也可以预加载关联后在集合层做汇总,写法更直观:

$collectionCenters = Supplier::where('supplier_type', 'juridic_person')
    ->with(['purchases.details' => fn($q) => $q->where('unit', 'kg')])
    ->get()
    ->map(function ($supplier) {
        $supplier->purchasesQtyKg = $supplier->purchases->sum(
            fn($purchase) => $purchase->details->sum('qty')
        );
        return $supplier;
    });

内容的提问来源于stack exchange,提问作者FreddicMatters

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:06:05