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

Laravel Eloquent分页使用withCount查询返回重复数据问题

问题根因

该问题核心是排序规则不稳定导致的分页数据重复:

  • 当前仅按聚合出来的count字段降序排序,当多个关注者的未读帖子数完全相同时,数据库没有次级排序规则约束行的返回顺序,每次分页查询时相同排序值的行返回顺序随机,不同分页区间就会出现重复的用户数据。
  • get()是一次性拉取全量数据,不存在分页偏移跳转逻辑,所以不会触发该问题。
修复方案

1. 追加稳定次级排序规则(首选方案)

给排序逻辑追加用户表唯一主键ID作为次级排序条件,保证不管第一排序值是否重复,整体排序结果固定,不会出现分页偏移混乱:

Auth::user()->followers()->withCount([
     'posts AS count' => fn($posts) => $posts
        ->where('status_id', 1)
        ->whereDoesntHave('views', fn($view) => $view->where('visitor', Auth::id()))
])
->orderBy('count', 'DESC')
// 追加唯一键作为次级排序,升序降序都可以,只要固定规则即可
->orderBy('id', 'ASC')
->paginate(8);

2. 手动生成分页器(复杂查询场景备选)

如果你的关联逻辑非常复杂,存在分页count统计和实际数据查询逻辑不一致的情况,可以手动指定分页逻辑,避免框架自动生成count查询时出错:

$baseQuery = Auth::user()->followers()->withCount([
     'posts AS count' => fn($posts) => $posts
        ->where('status_id', 1)
        ->whereDoesntHave('views', fn($view) => $view->where('visitor', Auth::id()))
])->orderBy('count', 'DESC')->orderBy('id', 'ASC');

$perPage = 8;
$currentPage = request()->input('page', 1);
$total = $baseQuery->count();
$pageData = $baseQuery->forPage($currentPage, $perPage)->get();

$paginator = new \Illuminate\Pagination\LengthAwarePaginator(
    $pageData,
    $total,
    $perPage,
    $currentPage,
    ['path' => request()->url(), 'query' => request()->query()]
);
效果验证

修改完成后可以分别拉取前两页的用户ID集合,检查两个集合是否存在交集,无交集则说明排序规则稳定,分页重复问题已解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:09:03