Laravel使用DB门面多表联查无报错但dd()返回空结果问题
问题诱因
- 重复声明查询表范围:你在
DB::table()中已经传入了多表列表,后续又调用fromRaw()重复定义FROM子句,会生成冗余、逻辑异常的SQL语句。 - 关联条件写法错误(核心原因):Laravel查询构造器默认会将
where()方法的第三个参数作为字面量值做参数绑定,你写的->where('products.id', '=', 'order_details.product_id')最终生成的SQL条件是WHERE products.id = 'order_details.product_id'——也就是拿产品ID和字符串常量做等值判断,而非和关联表的字段做匹配,自然查不到任何符合条件的数据。 - 分组逻辑和原生SQL不一致:你使用的
groupByRaw('bulan, name')是按SELECT别名分组,和原生SQL按分类ID、创建月份分组的逻辑不匹配,在MySQL严格模式下还可能触发语法报错,遇到同名分类时统计结果也会出错。
正确代码写法
推荐使用显式JOIN写法,可读性更高,也不容易出现关联条件写错的问题:
$categories = DB::table('order_details as od') ->join('products as p', 'p.id', '=', 'od.product_id') ->join('categories as c', 'c.id', '=', 'p.category_id') ->selectRaw(" monthname(od.created_at) as bulan, c.name as name, round(SUM(od.price * od.qty * (100 - od.discount)/ 100),2) as total ") ->groupByRaw('c.id, MONTH(od.created_at)') ->get(); dd($categories);
如果需要沿用原生SQL的隐式多表连接写法,注意字段间的关联判断必须使用whereColumn()方法,同时不要重复声明表来源:
$categories = DB::table('order_details as od, categories as c, products as p') ->selectRaw(" monthname(od.created_at) as bulan, c.name as name, round(SUM(od.price * od.qty * (100 - od.discount)/ 100),2) as total ") ->whereColumn('p.id', '=', 'od.product_id') ->whereColumn('p.category_id', '=', 'c.id') ->groupByRaw('c.id, MONTH(od.created_at)') ->get(); dd($categories);
排查小技巧:如果调整后查询结果仍不符合预期,可以把代码末尾的
->get()替换为->toSql(),打印最终生成的SQL语句,和你在MySQL中能正常执行的原生SQL逐段对比,就能快速定位差异点。
内容的提问来源于stack exchange,提问作者baihaqi
相关产品推荐
相关产品推荐

