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

Laravel 5.6中MySQL查询转Query Builder及DB::Raw报错求助

如何将指定MySQL查询转换为Laravel 5.6 Query Builder格式

问题背景

我需要把这条MySQL查询转换成Laravel 5.6的Query Builder格式:

SELECT paper_id,user_id,COUNT(payments.user_id),users.district
FROM payments
LEFT JOIN users ON payments.user_id = users.id
WHERE payments.paper_id=3
GROUP BY users.district HAVING COUNT(payments.user_id)>=0;

我先后尝试了两种写法,但都遇到了问题:

第一种尝试:使用DB::Raw

$data=DB::Raw('SELECT paper_id,user_id,COUNT(payments.user_id),users.district
                    FROM payments
                    LEFT JOIN users ON payments.user_id = users.id
                    WHERE payments.paper_id='.$paper_id.'
                    GROUP BY users.district HAVING 
                    COUNT(payments.user_id)>=0 
                    ');

问题:返回空响应 [{}]

第二种尝试:Query Builder写法

$data2=DB::table('payments')
                    ->leftJoin('users','payments.user_id','users.id')
                    ->select('paper_id','user_id','users.district',
                      DB::Raw('COUNT(payments.user_id)'))
                    ->where('payments.paper_id',$paper_id)
                    ->groupBy('users.district')
                    ->select(DB::Raw('HAVING COUNT(payments.user_id)>=0'))
                    ->get();

问题:出现SQL语法错误:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error
in your SQL syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near 'HAVING COUNT(payments.user_id)>=0 from
payments left join users on payments at line 1 (SQL: select HAVING
COUNT(payments.user_id)>=0 from payments left join users on
payments.user_id = users.id where payments.paper_id = 1 group by
users.district)


错误原因分析

  1. 第一种写法的问题:DB::Raw()只是创建了一个原始SQL表达式对象,但并没有执行查询操作,所以自然返回空结果。你需要用DB::select()来包裹这个表达式才能执行查询。
  2. 第二种写法的问题:你错误地把HAVING条件放到了select()方法里,Laravel Query Builder提供了专门的havingRaw()方法来处理这种原始的HAVING条件,这样写会直接导致SQL语法错误。

正确的Query Builder写法

下面是符合要求的正确写法,同时优化了字段命名和安全性:

$data = DB::table('payments')
    ->leftJoin('users', 'payments.user_id', '=', 'users.id')
    ->select(
        'payments.paper_id',
        'payments.user_id', // 注意:按district分组后,这个字段的值可能不唯一,建议根据实际需求调整(比如用MAX/聚合函数)
        'users.district',
        DB::raw('COUNT(payments.user_id) as user_count') // 给统计字段起别名,方便后续使用
    )
    ->where('payments.paper_id', $paper_id)
    ->groupBy('users.district')
    ->havingRaw('COUNT(payments.user_id) >= 0')
    ->get();

额外补充

  • 如果想修复第一种DB::Raw的写法,应该用参数绑定(避免SQL注入)并配合DB::select():
$data = DB::select(DB::raw('SELECT paper_id,user_id,COUNT(payments.user_id),users.district
                    FROM payments
                    LEFT JOIN users ON payments.user_id = users.id
                    WHERE payments.paper_id=?
                    GROUP BY users.district HAVING COUNT(payments.user_id)>=0'), [$paper_id]);
  • 另外,HAVING COUNT(payments.user_id)>=0这个条件其实可以省略,因为COUNT函数的结果永远是非负的,不会过滤掉任何分组结果。

内容的提问来源于stack exchange,提问作者Naveed Sheriffdeen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:19:49