【问题标题】:laravel 5 - paginate total() of a query with distinctlaravel 5 - 对具有不同的查询的总分页()
【发布时间】:2015-04-14 04:03:41
【问题描述】:

我有一个查询要根据数据透视表中的值获取照片,它存储“图片”和“标签”的关系:

#photos
$q = PicTag::select(DB::raw('distinct(pics.id)'),
                            'pics.url',
                            'pics.titel',
                            'pics.hits',
                            'pics.created_at',
                            'users.username',
                            'users.displayname')
                    ->leftJoin('pics', 'pics.id', '=', 'pic_tag.pic_id')
                    ->leftJoin('users','users.id','=','pics.user_id')
                    ->whereIn('pic_tag.tag_id', $tagids);

    if($cat)
        $q->where('typ',$cat);

    if($year)
        $q->where('jahrprod',$year);

$pics = $q->orderBy('pics.id','desc')
            ->paginate(30);

问题是,当为某张照片存储多个(相同)标签时,如“Tag”、“tag”和“tAG”。然后同一张照片将在我的画廊中显示 3 次。这就是我在查询中使用distinct 的原因。

那么图库就可以了,但是$pics->total() 没有显示“87 张照片”而是例如“90 张照片”,因为在分页中没有使用distinct。在 laravel 4 中,我使用了 groupBy('pics.id'),但这似乎不是最快的查询,而在 laravel 5 中,它给了我一个 total() 计数结果 1

我怎样才能获得正确的total() 值?

【问题讨论】:

    标签: pagination distinct laravel-5


    【解决方案1】:

    我知道这是一个古老的主题,但它可以帮助其他人。

    我遇到了同样的问题,我发现的唯一好的解决方案(低内存成本)是两次执行请求:

    $ids = DB::table('foo')
        ->selectRaw('foo.id')
        ->distinct()
        ->pluck('foo.id');
    
    $results = $query = DB::table('foo')
        ->selectRaw('foo.id')
        ->whereIn('foo.id', $ids)
        ->paginate();
    

    我尝试了 100k 结果,完全没有问题。

    【讨论】:

      【解决方案2】:

      Laravel 在复杂查询的分页中存在问题。所以你应该手动处理它们。在 laravel 5 中,我分两步完成:

      第 1 步:存储库方法:

        public function getByPage($page = 1, $limit = 10 , $provinceId ,    $cityId  , $expertiseId)
      {
          $array = ['users.deleted' => false];
          $array["users.approved"] = true;
          $array["users.is_confirmed"] = true;
          if($provinceId)
              $array["users.province_FK"] = $provinceId;
          if($cityId)
              $array["users.city_FK"] = $cityId;
          if($expertiseId)
              $array["ONJNCT_USERS_EXPERTISE.expertise_FK"] = $expertiseId;
      
          $results = new \stdClass();
          $results->page = $page;
          $results->limit = $limit;
          $results->totalItems = 0;
          $results->items = array();
          $users=  DB::table('users')
              ->distinct()
              ->select('users.*','ONDEGREES.name as drgree_name')
              ->join('ONJNCT_USERS_EXPERTISE', 'users.id', '=', 'ONJNCT_USERS_EXPERTISE.user_FK')
              ->join('ONDEGREES', 'users.degree_FK', '=', 'ONDEGREES.id')
              ->where($array)
              ->skip($limit * ($page - 1))->take($limit)->get();
          //$users = $usersQuery>skip($limit * ($page - 1))->take($limit)->get();
          $usersCount=  DB::table('users')
              ->select('users.*','ONDEGREES.name as drgree_name')
              ->join('ONJNCT_USERS_EXPERTISE', 'users.id', '=', 'ONJNCT_USERS_EXPERTISE.user_FK')
              ->join('ONDEGREES', 'users.degree_FK', '=', 'ONDEGREES.id')
              ->where($array)
              ->count(DB::raw('DISTINCT users.id'));
          $results->totalItems = $usersCount;
          $results->items = $users;
          return $results;
      }
      

      第 2 步: 在我的搜索控制器中:

        function search($provinceId , $cityId , $expertiseId){
           $page = Input::get('page', 1);
           $data = $this->userService->getByPage($page, 1 , $provinceId ,$cityId , $expertiseId);
          $users =  new LengthAwarePaginator($data->items, $data->totalItems, 1 , Paginator::resolveCurrentPage(),['path' => Paginator::resolveCurrentPath()]);
          return View::make('guest.search.searchResult')->with('users' ,$users);
      }
      

      它对我很有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-07
        • 2016-02-03
        • 2015-03-28
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        • 2014-04-03
        • 2015-01-02
        相关资源
        最近更新 更多