如何将含嵌套Join与Where的SQL转换为Laravel查询构建器语句
Laravel 查询构建器转换方案
以下是对应你提供SQL的Laravel查询构建器实现,完全匹配原SQL的逻辑:
子查询构建(对应原SQL中左连接的C表)
$subQuery = DB::table('prosys_prospect as A') ->leftJoin('prosys_visit as C', 'A.prs_id_prospect', '=', 'C.v_id_prospect') ->where('C.v_testdrive', '1') ->where('C.v_visit_number', '1') ->where('A.prs_kdcab', 'PK3A') ->whereBetween(DB::raw('DATE(prs_create_entry)'), ['2023-01-01', '2023-01-02']) ->select([ 'A.prs_id_sales', DB::raw('COUNT(C.v_id) as drive'), DB::raw('SUM(IF((A.prs_spk_no <> ""), 1, 0)) as spkdrive') ]) ->groupBy('A.prs_id_sales');
主查询构建
$result = DB::table('prosys_prospect as A') // 内连接prosys_sls表 ->join('prosys_sls as B', 'A.prs_id_sales', '=', 'B.nipsls') // 左连接上面定义的子查询,别名C ->leftJoinSub($subQuery, 'C', function($join) { $join->on('A.prs_id_sales', '=', 'C.prs_id_sales'); }) // 主查询过滤条件 ->where('B.expired', '0') ->where('A.prs_kdcab', 'PK3A') ->whereBetween(DB::raw('DATE(prs_create_entry)'), ['2023-01-01', '2023-01-02']) // 字段选择,原生函数用DB::raw包裹 ->select([ 'A.prs_id_sales', 'B.namesls', DB::raw('COUNT(A.prs_id) as pros'), DB::raw('IFNULL(C.drive, 0) as drive'), DB::raw('IFNULL(C.spkdrive, 0) as spkdrive'), DB::raw('SUM(IF((A.prs_spk_no <> ""), 1, 0)) as spk') ]) ->groupBy('B.nipsls') ->orderBy('B.namesls') ->get();
关键说明
- 子查询通过
DB::table()单独构建,再用leftJoinSub()方法实现左连接子查询,替代原生SQL中的子查询表定义 - 所有原生SQL函数(如
DATE()、IFNULL()、SUM(IF...))都需要用DB::raw()包裹,确保Laravel不会对这些语法做转义处理 - 内连接直接使用
join()方法,左连接子查询使用leftJoinSub(),参数分别为子查询实例、别名、关联条件闭包 whereBetween()配合DB::raw()处理日期范围过滤,和原SQL逻辑一致
内容的提问来源于stack exchange,提问作者Danura Aditya
相关产品推荐
相关产品推荐

