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

将Laravel中DB::Select原生查询转换为Query Builder以实现分页

将原生SQL转换为Laravel Query Builder并实现分页

当然可以把这段原生查询转成Query Builder,这样就能直接使用Laravel的分页功能了。转换后的代码如下:

public function getPopularBook()
{
    $books = DB::with('totalReview', function ($query) {
        $query->select('book_id', DB::raw('count(id) as review_count'))
              ->from('review')
              ->groupBy('book_id');
    })
    ->select('x.review_count', 'y.*')
    ->from('totalReview as x')
    ->leftJoinSub(function ($query) {
        $query->select('b.*', DB::raw('
            case 
                when ((now() >= d.discount_start_date and now() <= d.discount_end_date) or (now() >= d.discount_start_date and d.discount_end_date is null)) 
                then (b.book_price - d.discount_price)
                else b.book_price
            end as final_price
        '))
        ->from('book as b')
        ->rightJoin('discount as d', 'd.book_id', '=', 'b.id');
    }, 'y', 'x.book_id', '=', 'y.id')
    ->orderBy('x.review_count', 'desc')
    ->orderBy('y.final_price', 'asc')
    ->paginate(8);

    return $books;
}

关键转换点说明:

  • 用DB::with()定义原SQL中的CTE(totalReview),给评论数字段加了review_count别名,避免后续排序/查询时的歧义。
  • 用leftJoinSub()处理原查询里的子查询逻辑,保持了原有的discount右连book的关联关系,确保所有书籍都被包含。
  • 排序逻辑完全复刻原SQL,先按评论数降序,再按最终价格升序。
  • 最后用paginate(8)替换原有的LIMIT 8,Laravel会自动处理分页参数(比如URL中的page参数),返回包含分页导航信息的集合。

如果需要自定义分页的页码参数名、显示字段或分页路径,可以给paginate()传递额外参数,比如:

->paginate(8, ['*'], 'page_num', request()->get('page_num', 1));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:25:30