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

Laravel中SQL子查询关联转Eloquent/Query Builder求助

问题:将复杂SQL转换为Laravel Query Builder写法

原SQL查询语句:

SELECT opp_id, risk_study.rst_id, risk_study.rst_status
FROM opportunity
         LEFT JOIN risk_study ON risk_study.rst_id =
             (SELECT risk_study_quote_vehicle.rst_id
              FROM risk_study_quote_vehicle
                       INNER JOIN quote_vehicle ON quote_vehicle.quv_id = risk_study_quote_vehicle.quv_id
                       INNER JOIN quote ON quote.quo_id = quote_vehicle.quo_id
              WHERE quote.opp_id = opportunity.opp_id
              ORDER BY risk_study_quote_vehicle.rst_id DESC
              LIMIT 0,1)
WHERE 1 = 1
  AND opportunity.per_id_process = '5'
  AND opportunity.opp_locked = '1'

尝试的Laravel代码(无法获取risk_study表数据):

$opportunities = Opportunity::select('opp_id', 'risk_study.rst_id', 'risk_study.rst_status')
    ->leftJoin('risk_study', function ($join) {
        $join->on('risk_study.rst_id', '=', DB::raw('"SELECT risk_study_quote_vehicle.rst_id FROM risk_study_quote_vehicle INNER JOIN quote_vehicle ON quote_vehicle.quv_id = risk_study_quote_vehicle.quv_id INNER JOIN quote ON quote.quo_id = quote_vehicle.quo_id WHERE quote.opp_id = opportunity.opp_id ORDER BY risk_study_quote_vehicle.rst_id DESC LIMIT 0,1"'));
    })
    ->where([
        ['per_id_process', 5],
        ['opp_locked', 1],
    ])
    ->get();

解决方法

错误原因

你在DB::raw中给子查询套了双引号,导致整个子查询被当成字符串常量,而非可执行的SQL语句,无法正确匹配risk_study.rst_id,因此拿不到关联数据。

修正方案1:修复DB::raw写法

去掉子查询外层的双引号,让Laravel正确解析执行子查询:

$opportunities = Opportunity::select('opp_id', 'risk_study.rst_id', 'risk_study.rst_status')
    ->leftJoin('risk_study', function ($join) {
        $join->on('risk_study.rst_id', '=', DB::raw('(SELECT risk_study_quote_vehicle.rst_id FROM risk_study_quote_vehicle INNER JOIN quote_vehicle ON quote_vehicle.quv_id = risk_study_quote_vehicle.quv_id INNER JOIN quote ON quote.quo_id = quote_vehicle.quo_id WHERE quote.opp_id = opportunity.opp_id ORDER BY risk_study_quote_vehicle.rst_id DESC LIMIT 1)'));
    })
    ->where('per_id_process', 5)
    ->where('opp_locked', 1)
    ->get();

修正方案2:用Laravel子查询构建器(更优雅)

避免直接写原生SQL字符串,用Query Builder方式构建子查询,可读性和可维护性更好:

// 构建子查询
$subquery = DB::table('risk_study_quote_vehicle')
    ->select('risk_study_quote_vehicle.rst_id')
    ->join('quote_vehicle', 'quote_vehicle.quv_id', '=', 'risk_study_quote_vehicle.quv_id')
    ->join('quote', 'quote.quo_id', '=', 'quote_vehicle.quo_id')
    ->whereColumn('quote.opp_id', 'opportunity.opp_id')
    ->orderByDesc('risk_study_quote_vehicle.rst_id')
    ->limit(1);

// 主查询
$opportunities = Opportunity::select('opp_id', 'risk_study.rst_id', 'risk_study.rst_status')
    ->leftJoin('risk_study', 'risk_study.rst_id', '=', $subquery)
    ->where('per_id_process', 5)
    ->where('opp_locked', 1)
    ->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:01:12