Laravel 8 中如何实现嵌套SELECT子查询获取位置关联的最新站点更新时间
Laravel 8 查询每个关联模型最新记录的实现方法
原代码错误原因
你现有的查询逻辑存在问题:使用leftJoin关联sites表后直接按sites.location分组,在MySQL默认配置下groupBy会返回分组内第一条匹配记录,无法获取最新的updated_at值,和你需要的嵌套子查询逻辑不符。
实现方案1:使用查询构造器selectSub实现嵌套子查询
该方案完全对齐你给出的原生SQL逻辑,直接通过Laravel查询构造器生成对应语句:
$locations = DB::table('locations') ->select('locations.id', 'locations.name', 'locations.url') ->selectSub(function ($query) { $query->select('updated_at') ->from('sites') ->whereColumn('sites.location', 'locations.id') ->orderByDesc('updated_at') ->limit(1); }, 'latest_site_updated_at') ->where('locations.user', '=', $user->id) ->orderBy('latest_site_updated_at', 'asc') ->get();
如果对应location下没有关联的site记录,latest_site_updated_at字段会返回null,符合业务预期。
实现方案2:使用Eloquent关联withMax简化查询
如果你使用Eloquent模型进行开发,可先定义Location模型和Site模型的一对多关联,再通过Laravel内置的聚合方法实现需求,无需手动编写子查询:
- 首先在
App\Models\Location模型中定义关联:
public function sites() { return $this->hasMany(Site::class, 'location'); }
- 直接调用
withMax方法查询:
$locations = Location::where('user', $user->id) ->withMax('sites', 'updated_at') ->orderBy('sites_max_updated_at', 'asc') ->get();
查询结果中sites_max_updated_at字段即为对应location下最新site的updated_at值。
内容的提问来源于stack exchange,提问作者user16714187
相关产品推荐
相关产品推荐

