Laravel Eloquent多关联查询:获取供应商采购的付款总额
正确实现Laravel Eloquent查询供应商下各采购订单的付款总金额
你的代码存在几个问题:
- 拼写错误:
purcheses应为purchases - 预加载闭包内调用
get()是错误操作,会破坏Eloquent的预加载逻辑 - 直接在
payments关联的闭包里使用sum('amount')无法将付款总和绑定到对应的采购订单上
下面提供两种可靠的实现方式:
方法一:使用Laravel内置的withSum(推荐,Laravel 8.37+适用)
withSum是Laravel专门用来预加载关联模型字段总和的方法,用法简洁高效:
use App\Models\Supplier; $suppliers = Supplier::with([ 'purchases' => function ($query) { // 为每个采购订单预加载付款金额总和,字段名为payments_sum_amount $query->withSum('payments', 'amount')->latest(); } ])->latest()->get();
使用时直接访问采购订单的payments_sum_amount属性即可:
foreach ($suppliers as $supplier) { echo "供应商:{$supplier->name}\n"; foreach ($supplier->purchases as $purchase) { echo "采购订单 #{$purchase->id} 付款总金额:{$purchase->payments_sum_amount}\n"; } }
方法二:手动关联查询(兼容低版本Laravel)
如果你的Laravel版本低于8.37,可以通过leftJoin和groupBy手动计算总和:
use App\Models\Supplier; use Illuminate\Support\Facades\DB; $suppliers = Supplier::with([ 'purchases' => function ($query) { $query->select( 'purchases.*', DB::raw('COALESCE(SUM(payments.amount), 0) as payment_total') ) ->leftJoin('payments', 'payments.purchase_id', '=', 'purchases.id') ->groupBy('purchases.id') ->latest(); } ])->latest()->get();
这里用COALESCE确保没有付款的采购订单总金额显示为0,避免出现null。使用时访问purchase->payment_total即可。
注意:如果启用了MySQL严格模式,
groupBy需要包含purchases表的所有字段,或者在select里只指定需要的字段而非purchases.*。
内容的提问来源于stack exchange,提问作者Suraj Paudel
相关产品推荐
相关产品推荐

