laravel 5 - 具有distinct的查询的paginate total()

时间:2015-02-13 06:55:20

标签: pagination distinct laravel-5

我有一个查询,可以根据数据透视表中的值来获取照片,这些数据存储了" pics"和"标签":

#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);

问题是,对于某张照片,当存储多个(相同)标签时,如#34;标记","标记"和" tAG"。然后相同的照片将在我的画廊中显示3次。这就是我在查询中使用distinct的原因。

然后画廊没问题,但$pics->total()没有显示" 87张照片"但例如" 90张照片",因为distinct未用于分页。在laravel 4中,我使用groupBy('pics.id'),但这似乎不是最快的查询,而laravel 5它给我total()计数1的结果。

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

2 个答案:

答案 0 :(得分: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结果,并没有任何问题。

答案 1 :(得分:0)

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);
}

这对我有用!