如何在Laravel中实现给定的关联子查询SQL语句?
Laravel 实现该查询的三种常用方案
你可以根据自己的项目场景选择以下任意一种实现方式:
方案1:直接使用 whereRaw 适配原生SQL
最贴近你现有原生查询的写法,改动成本最低,参数绑定可避免SQL注入风险:
use Illuminate\Support\Facades\DB; $paquetes = DB::table('paquetes') ->whereRaw("( SELECT estatuses.nombre FROM estatus_paquete INNER JOIN estatuses ON estatuses.id = estatus_paquete.estatus_id WHERE estatus_paquete.paquete_id = paquetes.id ORDER BY estatus_paquete.created_at DESC LIMIT 1 ) = ?", ['En envio']) ->whereNull('deleted_at') ->get();
如果你已经为paquetes表创建了带软删除特性的Eloquent模型,whereNull('deleted_at')条件可以省略,Laravel会自动追加。
方案2:使用查询构造器生成子查询(无原生SQL片段)
完全基于Laravel查询构造器API实现,不需要手写SQL字符串,后续维护更方便:
use Illuminate\Support\Facades\DB; // 构造子查询逻辑 $latestEstatusQuery = DB::table('estatus_paquete') ->select('estatuses.nombre') ->join('estatuses', 'estatuses.id', '=', 'estatus_paquete.estatus_id') ->whereColumn('estatus_paquete.paquete_id', 'paquetes.id') ->orderByDesc('estatus_paquete.created_at') ->take(1); // 执行主查询 $paquetes = DB::table('paquetes') ->where($latestEstatusQuery, '=', 'En envio') ->whereNull('deleted_at') ->get();
方案3:基于Eloquent关联实现(复用性最高)
如果项目已经定义了Paquete、EstatusPaquete Eloquent模型,推荐用这种写法,后续可复用最新状态的关联逻辑:
- 先在
Paquete模型中定义最新状态的关联:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\SoftDeletes; class Paquete extends Model { use SoftDeletes; // 启用软删除则保留该行 public function latestEstatus(): HasOne { return $this->hasOne(EstatusPaquete::class)->latestOfMany(); } }
- 直接通过关联查询匹配条件的记录:
use App\Models\Paquete; $paquetes = Paquete::whereHas('latestEstatus', function ($query) { $query->join('estatuses', 'estatuses.id', '=', 'estatus_paquete.estatus_id') ->where('estatuses.nombre', 'En envio'); })->get();
内容的提问来源于stack exchange,提问作者Cesar
相关产品推荐
相关产品推荐

