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

Laravel paginate()嵌套关联加limit后无返回结果问题

Laravel Eloquent嵌套关联加limit后关联数据消失的原因与解决办法

问题原因

Eloquent预加载(with)的执行逻辑是:先查询出主模型的分页结果,再单独执行关联查询获取关联数据,最后通过外键把两者关联起来。当你在关联闭包里直接加limit(5)时,这个限制是针对所有满足active()条件的客户数据整体,只会取出前5条客户,而这5条很大概率和当前分页的10个产品没有外键匹配,最终导致所有产品的customers关联数据为空。

解决办法

方法1:用Laravel 8.42+的withLimit方法(推荐)

Laravel 8.42及以上版本专门新增了withLimit方法,能自动处理每个主模型的关联数量限制,确保每个产品都能拿到最多5条活跃客户:

$products = Products::withLimit(['customers' => function ($query) {
    $query->active();
}], 5)
    ->paginate(10);

或者更简洁的写法(如果只需要限制数量+默认查询条件):

$products = Products::withLimit(['customers' => 5])
    ->whereHas('customers', fn($query) => $query->active())
    ->paginate(10);

方法2:低版本Laravel兼容方案

如果你的Laravel版本低于8.42,可以用子查询或者窗口函数实现:

子查询方式
$products = Products::with(['customers' => function ($query) {
    $query->active()
        ->whereIn('id', function ($sub) {
            $sub->select('id')
                ->from('customers')
                ->whereColumn('customers.product_id', 'products.id')
                ->active()
                ->limit(5);
        });
}])
    ->paginate(10);
窗口函数方式(需数据库支持,如MySQL 8.0+)
$products = Products::with(['customers' => function ($query) {
    $query->active()
        ->selectRaw('customers.*, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY id) AS row_num')
        ->having('row_num', '<=', 5);
}])
    ->paginate(10);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:25:19