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

Laravel Eloquent BelongsToMany关联:如何获取中间表最新唯一记录?

在Laravel Eloquent中获取BelongsToMany关联的最新唯一Pivot记录

不需要仅通过join实现,用Eloquent关联配合子查询就能完成需求。下面给出两种可行的实现方式:

方式一:通过whereExists筛选最新记录

利用子查询判断当前pivot记录是否是对应state_id和installer_id分组中创建时间最晚的那条:

// State模型中的关联方法
public function installers()
{
    return $this->belongsToMany(Installer::class, 'installer_state')
        ->withPivot('baseline', 'created_at') // 加载需要的pivot字段
        ->whereExists(function ($query) {
            $query->select(DB::raw(1))
                ->from('installer_state as latest')
                ->whereColumn('latest.state_id', 'installer_state.state_id')
                ->whereColumn('latest.installer_id', 'installer_state.installer_id')
                ->groupBy('latest.state_id', 'latest.installer_id')
                ->havingRaw('MAX(latest.created_at) = installer_state.created_at');
        });
}

方式二:先获取最新Pivot记录ID再筛选

如果你的中间表ID是自增的(最新记录的ID最大),可以先查询每个分组的最大ID,再通过whereIn筛选:

// State模型中的关联方法
public function installers()
{
    // 子查询获取每个(state_id, installer_id)分组的最新pivot记录ID
    $latestPivotIds = DB::table('installer_state')
        ->select(DB::raw('MAX(id) as pivot_id'))
        ->groupBy('state_id', 'installer_id');

    return $this->belongsToMany(Installer::class, 'installer_state')
        ->withPivot('baseline', 'created_at')
        ->whereIn('installer_state.id', $latestPivotIds);
}

补充说明

  • 如果你不想修改默认的installers关联,可以新增一个专门的关联方法(比如latestInstallers),这样在需要获取最新记录时调用该方法即可。
  • 第一种方式不依赖ID自增,完全基于created_at判断,适用性更广;第二种方式性能略优,但需要确保ID和created_at的顺序一致。

调用方式和你预期的一样:

$state->installers()->get();

此时返回的Installer 1只会关联中间表的ID 2(state1的最新记录)和ID 3(state2的唯一记录)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:42:52