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

Laravel查询分页显示多余页面问题求助(疑似groupBy问题)

解决Laravel分页计数错误(distinct导致页数偏多)

问题出在paginate()的计数逻辑上:Laravel默认会对join后的全量记录做count(*),而distinct()是在最终返回结果时才去重,所以总条数计算的是未去重的记录数,导致分页链接多出来。

给你两种靠谱的解决办法:

方法一:先拿去重ID再分页查询

先获取符合条件的去重商家ID集合,再基于这些ID做分页查询,这样计数就会准确:

// 第一步:获取所有符合条件的去重商家ID,同时得到总条数
$affiliateIds = DB::table('ad_afiliado as af')
    ->join('af_promocion as promo', 'af.Clave', '=', 'promo.id_afiliado')
    ->where('promo.v_fin', '>', $FechaActual)
    ->where('af.Activo', '=', 'S')
    ->where('af.Categoria', 'like', $categoryStr)
    ->distinct('af.id_afiliado')
    ->pluck('af.id_afiliado');

// 第二步:基于ID集合分页查询详情,每页9条
$afiliates = DB::table('ad_afiliado as af')
    ->select('af.logo_url', 'af.NombreComercial', 'af.Destacado', 
        'af.id_afiliado', 'af.Clave')
    ->whereIn('af.id_afiliado', $affiliateIds)
    ->orderBy('af.NombreComercial')
    ->orderBy(DB::raw('RAND()'))
    ->paginate(9);

方法二:用groupBy+手动封装分页对象

用groupBy确保数据去重,然后手动计算总条数,再封装成分页对象:

// 计算去重后的总记录数
$total = DB::table('ad_afiliado as af')
    ->join('af_promocion as promo', 'af.Clave', '=', 'promo.id_afiliado')
    ->where('promo.v_fin', '>', $FechaActual)
    ->where('af.Activo', '=', 'S')
    ->where('af.Categoria', 'like', $categoryStr)
    ->groupBy('af.id_afiliado')
    ->count();

// 获取当前页码,默认第1页
$page = request()->page ?? 1;
$perPage = 9;
$skip = ($page - 1) * $perPage;

// 查询当前页的数据
$afiliatesData = DB::table('ad_afiliado as af')
    ->select('af.logo_url', 'af.NombreComercial', 'af.Destacado', 
        'af.id_afiliado', 'af.Clave')
    ->join('af_promocion as promo', 'af.Clave', '=', 'promo.id_afiliado')
    ->where('promo.v_fin', '>', $FechaActual)
    ->where('af.Activo', '=', 'S')
    ->where('af.Categoria', 'like', $categoryStr)
    ->groupBy('af.id_afiliado')
    ->orderBy('af.NombreComercial')
    ->orderBy(DB::raw('RAND()'))
    ->skip($skip)
    ->take($perPage)
    ->get();

// 封装成分页对象,保持Laravel分页的原有功能
$afiliates = new \Illuminate\Pagination\LengthAwarePaginator(
    $afiliatesData,
    $total,
    $perPage,
    $page,
    [
        'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath(),
        'pageName' => 'page',
    ]
);

核心原因:原代码里的distinct()只影响最终返回的数据集,但分页计数时执行的是不带distinct的count查询,导致总条数统计的是join后的重复记录数,自然分页页数就多了。

内容的提问来源于stack exchange,提问作者Pepe F.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:55:21