欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel - Union + Paginate at the same time?


I am trying to union 2 tables (recipes + posts) and add ->paginate(5) to the queries.

But for some reason i get this error:

Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select count(*) as aggregate from posts

My code:

$recipes = DB::table("recipes")->select("id", "title", "user_id", "description", "created_at")
                    ->where("user_id", "=", $id);

$items = DB::table("posts")->select("id", "title", "user_id", "content", "created_at")
                ->where("user_id", "=", $id)
                ->union($recipes)
                ->paginate(5)->get();

Am i doing something wrong?

  • Without ->paginate(5) the query works fine.
shareimprove this question
 

5 Answers 正确答案

You're right, pagination cause problem. Right now, you can create a view and query the view instead of the actual tables, or create your Paginator manually:

$page = Input::get('page', 1);
$paginate = 5;

$recipes = DB::table("recipes")->select("id", "title", "user_id", "description", "created_at")
            ->where("user_id", "=", $id);
$items = DB::table("posts")->select("id", "title", "user_id", "content", "created_at")
            ->where("user_id", "=", $id)
            ->union($recipes)
            ->get();

$slice = array_slice($items, $paginate * ($page - 1), $paginate);
$result = Paginator::make($slice, count($items), $paginate);

return View::make('yourView',compact('result'));
shareimprove this answer
 
   
Thanks! how would you add orderBy to the union query? i tried to add it after the ->union but the "order by" ends up within one of the parentheses (version 4.2.8). – George Aug 23 '14 at 19:11

order by

 $page = Input::get('page', 1);

 $paginate = 5;

 $recipes = DB::table("recipes")->select("id", "title", "user_id", "description", "created_at")
                ->where("user_id", "=", $id);
$items = DB::table("posts")->select("id", "title", "user_id", "content", "created_at")
            ->where("user_id", "=", $id)
            ->union($recipes)
            ->orderBy('created_at','desc')
            ->get();

$slice = array_slice($items, $paginate * ($page - 1), $paginate);
$result = Paginator::make($slice, count($items), $paginate);

return View::make('yourView',compact('result'))->with( 'result', $result );

View page :

   @foreach($result as $data)
  {{ $data->your_column_name;}}
 @endforeach 

  {{$result->links();}}   //for pagination

its help to more peoples.. because nobody cant understand show data in view page union with pagination and orderby .. thank u

shareimprove this answer
 
3 
Loading all the rows in php and then slicing them is not very efficient, especially for large tables. – Alexandru Eftimie Dec 9 '16 at 17:44

I faced this kind of issue already. I found a thread also not about pagination but about unions.

Please see this link : Sorting UNION queries with Laravel 4.1

@Mohamed Azher has shared a nice trick and it works on my issue.

$query = $query1->union($query2);
$querySql = $query->toSql();
$query = DB::table(DB::raw("($querySql order by foo desc) as a"))->mergeBindings($query);

This creates an sql like below:

select * from (
  (select a as foo from foo)
  union
  (select b as foo from bar)
) as a order by foo desc;

And you can already utilize Laravel's paginate same as usual like $query->paginate(5)(but you have to fork it a bit to fit to your problem)

shareimprove this answer
 

I had this same problem, and unfortunately I couldn't get the page links with {{ $result->links() }}, but I found another way to write the pagination part and the page links appears

Custom data pagination with Laravel 5

//Create a new Laravel collection from the array data
$collection = new Collection($searchResults);

//Define how many items we want to be visible in each page
$perPage = 5;

//Slice the collection to get the items to display in current page
$currentPageSearchResults = $collection->slice($currentPage * $perPage, $perPage)->all();

//Create our paginator and pass it to the view
$paginatedSearchResults= new LengthAwarePaginator($currentPageSearchResults, count($collection), $perPage);

return view('search', ['results' => $paginatedSearchResults]);
shareimprove this answer
 
$page = Input::get('page', 1);
$paginate = 5;
$recipes = DB::table("recipes")->select("id", "title", "user_id", "description", "created_at")
            ->where("user_id", "=", $id);
$items = DB::table("posts")->select("id", "title", "user_id", "content", "created_at") ->where("user_id", "=", $id)->union($recipes)->get()->toArray();
$slice = array_slice($items, $paginate * ($page - 1), $paginate);
$result = new Paginator($slice , $paginate);
shareimprove this answer
 
   
Code-only answers do very little to educate SO readers. Your answer may or may not be a correct answer, but it is in the moderation queue after being marked as "low-quality". Please take a moment to improve your answer with an explanation. – mickmackusa Apr 20 at 3:40

来自 https://stackoverflow.com/questions/25338456/laravel-union-paginate-at-the-same-time


普通分类: