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

Laravel Eloquent查询过滤负值结果后如何实现分页

解决方案

方案1(推荐):数据库层直接过滤,原生支持分页

不需要先查询全量数据到内存再做集合过滤,直接在查询阶段就筛选掉剩余天数小于0的逾期记录,后续链式调用paginate()就能正常工作,性能最优、代码最简洁。

因为Days是SQL计算生成的字段别名,用having方法做筛选即可,不需要重复写日期计算逻辑:

$resting_time = DB::table('alquiler')
    ->join('socio','alquiler.soc_id','=','socio.id')
    ->join('pelicula','alquiler.pel_id','=','pelicula.id')
    ->select(
        'socio.soc_nombre',
        'pelicula.pel_nombre',
        'alquiler.created_at',
        DB::raw("DATEDIFF(alq_fecha_hasta,NOW()) AS Days")
    )
    ->having('Days', '>=', 0)
    ->orderBy('Days','asc')
    ->paginate(6);

这个写法和你最初可正常分页的代码逻辑几乎一致,只是多了一行筛选条件,返回的分页对象和之前的用法完全兼容,不需要修改前端分页渲染的代码。

方案2:集合手动分页(仅适用于必须做内存复杂过滤的场景)

如果你的筛选逻辑复杂到无法直接用SQL实现,必须先取全量数据再通过集合方法处理,可以手动调用Laravel内置的分页类实现和paginate()一致的效果:

// 全量查询、过滤、排序
$filteredRecords = DB::table('alquiler')
    ->join('socio','alquiler.soc_id','=','socio.id')
    ->join('pelicula','alquiler.pel_id','=','pelicula.id')
    ->select(
        'socio.soc_nombre',
        'pelicula.pel_nombre',
        'alquiler.created_at',
        DB::raw("DATEDIFF(alq_fecha_hasta,NOW()) AS Days")
    )
    ->get()
    ->filter(fn($item) => $item->Days >= 0)
    ->sortBy('Days');

// 读取分页参数
$perPage = 6;
$currentPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
// 截取当前页的数据
$pageItems = $filteredRecords->forPage($currentPage, $perPage)->values();

// 生成分页对象,和原生paginate返回值用法完全一致
$resting_time = new \Illuminate\Pagination\LengthAwarePaginator(
    $pageItems,
    $filteredRecords->count(),
    $perPage,
    $currentPage
);

注意:该方案会把所有符合条件的记录加载到内存,表数据量超过千条级别时会明显拖慢接口响应,非必要场景优先选择第一种方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:54:20