使用 paginate 分页的同时 distinct 去重,会导致分页数出错

            $result = $db->table('k_flow')
                ->join('k_flow_operate', 'k_flow_operate.flow_id', '=', 'k_flow.flow_id')
                ->where('k_flow.is_finish', 2)
                ->where('k_flow_operate.operator', $userName)
                ->whereIn('k_flow_operate.status', [2, 3, 4, 5, 6, 7, 8, 9])
                ->orderBy('k_flow.add_time', 'desc')
                ->select('k_flow.*')
                ->distinct()
                ->paginate(15);

执行以上语句时,会返回如下结果

LengthAwarePaginator {#348 ▼
  #total: 16
  #lastPage: 2
  #items: Collection {#335 ▼
    #items: array:8 [▼
      0 => {#338 ▶}
      1 => {#331 ▶}
      2 => {#339 ▶}
      3 => {#332 ▶}
      4 => {#341 ▶}
      5 => {#324 ▶}
      6 => {#330 ▶}
      7 => {#340 ▶}
    ]
  }
  #perPage: 15
  #currentPage: 1
  #path: "http://config.admin.kugou.net/config/setting/flow/2"
  #query: []
  #fragment: null
  #pageName: "page"
  +onEachSide: 3
  #options: array:2 [▶]
}

可以看到,实际上去重后的数据是8条,但是分页里的数据还是按照没去重之前的输出,这样导致了分页出错。
请问有哪位大佬遇到过类似的问题么?有没有解决的方案提供?
ps:网上查阅时,有人说paginate有第二个参数,然鹅,文档里写的很明确:
传递给 paginate 方法的唯一参数是你希望 "每页" 展示的项目数量

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 7

虽然没遇过这种问题,但是我觉得可以打印 sql 看看,实在不行手动创建分页也可以嘛

4年前 评论

其实思路是有的,先删除 paginate 然后打印一下 distinct 获取到的数据,看看其获取到的是不是一个模型实例,ps:貌似只有模型实例才能进行分页0.0

4年前 评论

paginate 不止一个参数的,你自己看源码就知道了
还有就是你这样每次分页返回的条数不一样真的好吗?

4年前 评论
海猫 (楼主) 4年前
66

这个问题一直存在,因为分页先会执行一遍

select * 

获取总数 所以你分页上去重并不会影响 他获取总数的SQL
paginate 不止一个参数 的哦

    /**
     * Paginate the given query.
     *
     * @param  int  $perPage
     * @param  array  $columns
     * @param  string  $pageName
     * @param  int|null  $page
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     *
     * @throws \InvalidArgumentException
     */
    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
    {
        $page = $page ?: Paginator::resolveCurrentPage($pageName);

        $perPage = $perPage ?: $this->model->getPerPage();

        $results = ($total = $this->toBase()->getCountForPagination())
                                    ? $this->forPage($page, $perPage)->get($columns)
                                    : $this->model->newCollection();

        return $this->paginator($results, $total, $perPage, $page, [
            'path' => Paginator::resolveCurrentPath(),
            'pageName' => $pageName,
        ]);
    }

     /**
     * Get the count of the total records for the paginator.
     *
     * @param  array  $columns
     * @return int
     */
        public function getCountForPagination($columns = ['*'])
4年前 评论

用 GROUP BY 来代替 distinct,效果会不会好一些?

多说一句,GROUP BY 的性能比 distinct 更好

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!