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
相关产品推荐
相关产品推荐

