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

如何编写Eloquent多表关联查询以统计各物料交易重量总和

统计各类物料交易重量总和的Eloquent查询

我有4张数据表:materials、advertisements、offerrequests、transactions,需要编写Eloquent查询语句,统计每类参与交易的物料对应的交易重量总和。我尝试的查询代码如下:

Transaction::select(DB::raw("IF(transactions.is_sell = '1', advertisements.weight, offerrequests.weight) as weight"),DB::raw("IF(transactions.is_sell = '1', advertisements.material_id, offerrequests.material_id) as material_id"))
            ->leftJoin('advertisements', function ($join) {
                $join->on('advertisements.id', '=', 'transactions.post_id');
            })
            ->leftJoin('offerrequests', function ($join) {
                $join->on('offerrequests.id', '=', 'transactions.post_id');
            })
            ->leftJoin('materials', function ($join) {
                $join->on('materials.id', '=', 'material_id');
            })
           ->groupBy('material_id')->get();

数据表结构及数据

Transactions表

idmaterial_idis_sellpost_id
11120

Advertisements表

idmaterial_idweight
1110

Offerrequests表

idmaterial_idweight
1120

Materials表

idname
1plastic
2paper

期望查询结果

weightmaterial
30Plastic
50paper

修正后的查询代码

原查询存在未对重量求和、多表左连接易产生笛卡尔积、关联物料表时字段歧义等问题,以下是修正后的Eloquent查询:

$transactionStats = Transaction::select(
    DB::raw('SUM(CASE WHEN transactions.is_sell = 1 THEN advertisements.weight ELSE offerrequests.weight END) AS total_weight'),
    DB::raw('UPPER(LEFT(materials.name, 1)) || SUBSTRING(materials.name, 2) AS material')
)
->leftJoin('advertisements', function ($join) {
    $join->on('advertisements.id', '=', 'transactions.post_id')
         ->where('transactions.is_sell', 1);
})
->leftJoin('offerrequests', function ($join) {
    $join->on('offerrequests.id', '=', 'transactions.post_id')
         ->where('transactions.is_sell', 0);
})
->join('materials', function ($join) {
    $join->on('materials.id', '=', DB::raw('CASE WHEN transactions.is_sell = 1 THEN advertisements.material_id ELSE offerrequests.material_id END'));
})
->groupBy('materials.id', 'materials.name')
->get();

关键调整说明

  1. 用SUM()聚合函数计算每类物料的总交易重量
  2. 根据is_sell值分别关联对应表,避免无效连接
  3. 明确物料ID的来源,消除字段歧义
  4. 可选:通过字符串函数将物料名称首字母大写,匹配期望结果格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:07:52