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

Laravel查询构建器实现带MAX子查询的LEFT JOIN的正确方法

问题:Laravel查询构建器实现带关联子查询的LEFT JOIN

原生SQL查询

SELECT *
FROM collection_companies cc 
LEFT JOIN collection_company_links ccl ON cc.id = ccl.collection_company_id 
    AND ccl.id  = 
        (
           SELECT MAX(id) 
           FROM collection_company_links ccl2  
           WHERE ccl2.collection_company_id = ccl.collection_company_id
        )

尝试的Laravel查询构建器代码(存在问题)

$data = DB::table('collection_companies as cc')
      ->leftJoin('collection_company_links as ccl', 'cc.id', '=', 'ccl.collection_company_id')
      ->where('ccl.id', function ($query) {
        $query->select(DB::raw("MAX(id)"))->from('collection_company_links as ccl2')
        ->where('ccl2.collection_company_id', 'ccl.collection_company_id');
      });

问题原因

代码中where('ccl2.collection_company_id', 'ccl.collection_company_id')会把ccl.collection_company_id当作字符串字面量处理,而非关联表的字段引用,导致子查询逻辑失效。

正确实现方式

要匹配原生SQL的逻辑,需要将关联条件全部放在LEFT JOIN的ON子句中,同时用whereColumn方法来比较数据库字段,避免被当作字符串处理。

正确代码如下:

$data = DB::table('collection_companies as cc')
    ->leftJoin('collection_company_links as ccl', function ($join) {
        $join->on('cc.id', '=', 'ccl.collection_company_id')
             ->whereColumn('ccl.id', function ($query) {
                 $query->select(DB::raw('MAX(id)'))
                       ->from('collection_company_links as ccl2')
                       ->whereColumn('ccl2.collection_company_id', 'ccl.collection_company_id');
             });
    })
    ->get();

关键说明

  • 使用leftJoin的闭包形式,把所有关联条件写入ON子句,和原生SQL逻辑完全对齐,避免破坏LEFT JOIN的特性。
  • 用whereColumn替代普通where,专门用来比较两个数据库字段,确保字段引用的正确性。
  • 子查询内部同样使用whereColumn关联字段,保证子查询能正确关联外部表的字段值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:30:12