Laravel关联查询:仅关联按created_at排序的最新关联记录问题
解决关联一对多表时仅获取每条主记录对应最新关联记录的问题
要实现每个meter仅关联最新的contract记录,你需要先通过子查询锁定每个meter对应的最新合同,再将该结果与主查询关联,避免关联所有合同数据。具体实现如下:
修改后的代码
if (! is_null($request->input('filters.suppliers'))) { $companies->join('sites as s1', 'companies.id', '=', 's1.company_id'); $companies->join('meters as m1', 's1.id', '=', 'm1.site_id'); // 子查询:按meter分组,获取每个meter的最新合同创建时间 $latestContractTimes = DB::table('contracts') ->select('meter_id', DB::raw('MAX(created_at) as latest_created_at')) ->groupBy('meter_id'); // 关联子查询与contracts表,锁定每个meter的最新合同记录 $companies->joinSub($latestContractTimes, 'lct', function ($join) { $join->on('m1.id', '=', 'lct.meter_id'); }) ->join('contracts as c1', function ($join) use ($request) { $join->on('lct.meter_id', '=', 'c1.meter_id') ->on('lct.latest_created_at', '=', 'c1.created_at') ->whereIn('c1.supplier_id', $request->input('filters.suppliers')); }); }
补充说明
- 处理重复时间场景:如果同一
meter下存在多条created_at相同的合同记录,可将子查询改为获取MAX(id)(假设id自增),通过meter_id和latest_id关联contracts表,确保唯一锁定最新记录。 - 性能优化建议:给
contracts表添加联合索引(meter_id, created_at),能大幅提升子查询的分组效率。
内容的提问来源于stack exchange,提问作者Lewis Hayter
相关产品推荐
相关产品推荐

