如何在Laravel Eloquent多关联表中执行GROUP BY分组操作
在Laravel Eloquent多关联表中实现GROUP BY分组操作
一、主表(Invoice)直接分组
如果需要对Invoice主表字段分组(比如按type分组统计各类型发票数量),直接在查询链中添加groupBy,配合聚合函数使用即可:
$invoices = Invoice::select('type', DB::raw('COUNT(id) as invoice_count'), DB::raw('SUM(total_amount) as total')) ->groupBy('type') ->latest('invoice_count') ->get();
二、基于关联表字段分组
如果要按关联表(如invoice_items或item_title)的字段分组(比如按商品名称统计总金额),需要通过join关联对应表后再执行分组:
$itemStats = Invoice::select('item_title.name', DB::raw('SUM(invoice_items.amount) as total_amount')) ->join('invoice_items', 'invoices.id', '=', 'invoice_items.invoice_id') ->join('item_title', 'invoice_items.item_id', '=', 'item_title.id') ->groupBy('item_title.name') ->orderBy('total_amount', 'desc') ->get();
三、保留关联加载同时分组
若要保留原有关联加载逻辑,同时对主表分组,需将主表中SELECT的非聚合字段全部加入groupBy:
$invoices = Invoice::select('id', 'date', 'type') ->groupBy('id', 'date', 'type') ->latest('id') ->with('invoice_items:invoice_id,item_id,amount', 'invoice_items.item_title:id,name') ->get();
注意:MySQL开启
strict模式时,SELECT中的非聚合字段必须全部包含在GROUP BY子句中,否则会触发SQL错误。
四、分组后聚合关联表数据
如果要在主表分组的同时,聚合关联表的统计数据(比如每张发票的总金额),可以用withSum这类关联聚合方法:
$invoices = Invoice::select('id', 'date', 'type') ->withSum('invoice_items', 'amount') // 自动生成invoice_items_sum_amount字段 ->groupBy('id', 'date', 'type') ->latest('id') ->get();
返回的每个Invoice模型会携带invoice_items_sum_amount属性,对应该发票所有项的金额总和。
内容的提问来源于stack exchange,提问作者mahbub
相关产品推荐
相关产品推荐

