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

如何使用Eloquent实现给定原生SQL的子查询写法

Eloquent ORM 实现方案

以下两种写法生成的SQL与你提供的原生语句逻辑完全一致,可根据项目使用的Laravel版本选择。

前置说明

  • 需提前创建对应模型:Client 对应clients表,ClientsSummaryData对应clients_summary_data表
  • 若Client模型引入了SoftDeletes软删trait,框架会自动追加where deleted_at is null条件,无需手动编写

推荐写法(Laravel 6+ 通用,返回Eloquent模型集合)

该写法无需额外定义模型关联,直接通过selectSub拼接SELECT子句中的子查询,返回结果字段名与原生SQL完全对齐:

// 构建统计last_buy最大值的子查询
$lastBuySub = ClientsSummaryData::selectRaw('max(last_buy)')
    ->whereColumn('client_id', 'clients.id');

// 主查询
$clients = Client::select('id', 'sap_id')
    ->selectSub($lastBuySub, 'last_buy')
    // 未启用软删时需要手动加下这行,启用软删可省略
    ->whereNull('deleted_at')
    ->get();

如果你的项目是Laravel 8及以上版本,也可以通过关联聚合的withMax方法实现,代码更简洁:

  1. 先在Client模型中定义一对多关联
// app/Models/Client.php
public function summaryData()
{
    return $this->hasMany(ClientsSummaryData::class, 'client_id');
}
  1. 直接调用聚合方法查询
$clients = Client::select('id', 'sap_id')
    ->withMax('summaryData', 'last_buy')
    ->get();

注意:withMax返回的结果中,最大值会存储在summary_data_max_last_buy动态属性上,若需要字段名直接为last_buy,请使用上面的selectSub写法。


原生查询构造器写法(无模型依赖)

如果不需要返回Eloquent模型实例,可以直接用查询构造器实现,兼容所有Laravel版本:

$lastBuySub = \DB::table('clients_summary_data as csd')
    ->selectRaw('max(csd.last_buy)')
    ->whereColumn('csd.client_id', 'c.id');

$clients = \DB::table('clients as c')
    ->select('c.id', 'c.sap_id')
    ->selectSub($lastBuySub, 'last_buy')
    ->whereNull('c.deleted_at')
    ->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:30:44