Laravel查询构造器实现左连接统计SQL结果不一致问题
我来帮你把原SQL转换成正确的Laravel查询构造器代码,顺便排查下可能导致结果不一致的问题~
正确的Laravel查询构造器实现
以下是完全对应你原SQL的代码,应该能解决结果不一致的问题:
User::select( 'users.id as id', 'users.name as name', DB::raw('count(casos.user_id) as casos'), DB::raw('cast(SUM(CASE WHEN casos.status = 2 THEN 1 ELSE 0 END) AS SIGNED INTEGER) AS pendientes'), DB::raw('cast(SUM(CASE WHEN casos.status = 0 THEN 1 ELSE 0 END) AS SIGNED INTEGER) AS enviados') ) ->leftJoin('casos', 'casos.user_id', '=', 'users.id') ->where('users.lab_id', 2) ->where('users.admin', 0) ->groupBy('users.id', 'users.name') // 严格模式下必须包含所有非聚合的select字段 ->get();
关键注意点(也是你之前可能踩坑的地方)
- 必须用
DB::raw()包裹原生SQL逻辑:原SQL里的count、SUM(CASE...)、cast这些都是原生SQL语法,直接写在select里的话,Laravel会把它们当成普通字段名解析,这绝对是你结果不对的核心原因。你之前写的DB::ra应该是没写完DB::raw(),补全就好啦。 - 左连接的正确写法:用
leftJoin()方法对应原SQL的left join,参数顺序是关联表名、关联字段的对应关系,和原SQL的连接条件完全一致。 - 分组的严格要求:如果你的Laravel开启了严格模式(默认是开的),
groupBy必须包含所有select里的非聚合字段,也就是users.id和users.name,不然数据库会抛出分组错误。如果你的数据库允许宽松分组,只写users.id也能运行,但推荐严格遵循规范,避免后续出问题。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

