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

Laravel 5.4中获取关联表最新关联数据的预加载问题

解决Laravel一对多关联获取每条父模型最新子记录的问题

这个问题我之前也碰到过,咱们来一步步拆解解决它~

为什么你的代码只返回第一条关联记录?

你原来的查询里,在with的闭包中直接调用first(),这个操作是对整个关联表集合执行排序后取第一条,而不是为每一条purchase单独获取它对应的最新历史记录。所以最终只有第一条purchase能拿到关联数据,其他的都没有匹配结果。

解决方案1:定义专属的hasOne关联(推荐)

最优雅的方式是在Purchases模型里新增一个hasOne类型的关联,专门用来获取该采购记录的最新历史:

// Purchases.php 模型文件
public function latestAccountsPurchaseHistory()
{
    // 假设关联外键是purchase_id,按id倒序取最新的一条
    return $this->hasOne(AccountsPurchaseHistory::class, 'purchase_id')->latest('id');
}

然后查询的时候直接调用这个关联即可:

$purchases = Purchases::with('latestAccountsPurchaseHistory')
    ->where('status', 'extended')
    ->orderBy('id', 'DESC')
    ->get();

这样每条status为extended的purchase都会带上自己对应的最新历史记录,而且这个关联可以在其他地方复用,代码更整洁。

解决方案2:使用子查询过滤关联记录

如果不想新增模型关联,也可以在with的闭包里用子查询筛选出每个purchase对应的最大id的历史记录:

use Illuminate\Support\Facades\DB;

$purchases = Purchases::with(['accounts_purchase_histories' => function ($query) {
    $query->whereIn('id', function ($subQuery) {
        $subQuery->select(DB::raw('MAX(id)'))
            ->from('accounts_purchase_histories')
            ->groupBy('purchase_id');
    });
}])
->where('status', 'extended')
->orderBy('id', 'DESC')
->get();

这里通过子查询先找出每个purchase_id对应的最大历史记录id,再用这些id过滤关联数据,确保每条purchase只拿到自己的最新历史。

小提醒

注意你的关联名称accounts_purchase_historie应该是复数形式accounts_purchase_histories,可能是笔误,修正后能避免不必要的错误哦~

内容的提问来源于stack exchange,提问作者Mutasim Fuad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:10:55