Laravel - Объединение + Разбиение на страницы одновременно?


Я пытаюсь объединить 2 таблицы (рецепты + сообщения) и добавить -> разбиение на страницы (5) в запросы.

Но по какой-то причине я получаю эту ошибку:

Нарушение количества элементов: 1222 Используемые операторы SELECT имеют разное количество столбцов (SQL: (выберите количество (*) в качестве агрегата из posts

Мой код:

$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();

Я делаю что-то не так?

  • Без ->разбиения на страницы(5) запрос работает нормально.
Author: George, 2014-08-16

7 answers

Вы правы, проблема с разбиением на страницы. Прямо сейчас вы можете создать представление и запросить представление вместо фактических таблиц, или создайте свой Paginator вручную:

$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->toArray(), $paginate * ($page - 1), $paginate);
$result = Paginator::make($slice, count($items), $paginate);

return View::make('yourView',compact('result'));
 6
Author: Razor, 2018-05-16 22:47:19

Я уже сталкивался с подобной проблемой. Я нашел тему также не о pagination, а о unions.

Пожалуйста, посмотрите эту ссылку: Сортировка запросов ОБЪЕДИНЕНИЯ с помощью Laravel 4.1

@Mohamed Azher поделился хорошим трюком, и он работает в моей проблеме.

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

Это создает sql, как показано ниже:

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

И вы уже можете использовать paginate Ларавеля так же, как обычно, как $query->paginate(5). (но вам придется немного раскошелиться, чтобы соответствовать вашей проблеме)

 3
Author: jdme, 2017-05-23 12:17:57

Заказать по

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

Страница просмотра:

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

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

Его помощь большему числу народов.. потому что никто не может понять, как отображать данные в объединении страниц просмотра с разбиением на страницы и порядком.. спасибо вам

 2
Author: Tamilheartz, 2015-06-08 10:39:29

У меня была та же проблема, и, к сожалению, я не смог получить ссылки на страницы с помощью {{ $result->links() }}, но я нашел другой способ написать часть разбиения на страницы, и ссылки на страницы появляются

Пользовательская разбивка данных на страницы с помощью 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]);
 1
Author: Marcelo Bruzetti, 2016-12-03 00:36:55

Повторение jdmeответа более элегантным методом из Illuminate\Database\Query\Builder.

$recipes = DB::table("recipes") ..
$items = DB::table("posts")->union($recipes) ..

$query = DB::query()
    ->fromSub($items, "some_query_name");

// Let's paginate!
$query->paginate(5);

Надеюсь, это поможет!

 0
Author: Johnny, 2018-06-10 08:22:27

Я знаю, что этот ответ слишком запоздал. Но я хочу поделиться своими проблемами и своим решением.

Мои проблемы:

  1. Объединяйтесь со многими таблицами одновременно
  2. ОБЪЕДИНЕНИЕ
  3. Разбиение на страницы (Должно использоваться, потому что я должен использовать общую тему для отображения разбиения на страницы. Если я сделал собственный обычай для разбиения на страницы, он не будет соответствовать текущему. И в будущем общая тема может быть изменена.)
  4. Большие данные: просмотр занял 4 секунды, загрузка страницы заняла 4 секунды => всего 8 секунд. (Но если я задам условие внутри этого представления, то в общей сложности это займет не менее 1 секунды.)

Запрос

※ Это образец. MariaDB, около 146 000 записей.

SELECT A.a_id
     , A.a_name
     , B.organization_id
     , B.organization_name
  FROM customers A 
    LEFT JOIN organizations B ON (A.organization_id = B.organization_id)

UNION ALL

SELECT A.a_id
     , A.a_name
     , B.organization_id
     , B.organization_name
  FROM employees A 
    LEFT JOIN organizations B ON (A.organization_id = B.organization_id)

Решение

Ссылка из www.tech-corgi.com (やり方2), я обновил свой PHP-код, чтобы отфильтровать внутри своего запроса, а затем вызвать paginate в обычном режиме.

Я должен добавить условие (фильтр) перед получением больших записей. В этом примере идентификатор организации_id.

$query = "
    SELECT A.a_id
         , A.a_name
         , B.organization_id
         , B.organization_name
      FROM customers A 
        LEFT JOIN organizations B ON (A.organization_id = B.organization_id)
     WHERE 1 = 1
       AND B.organization_id = {ORGANIZATION_ID}

    UNION ALL

    SELECT A.a_id
         , A.a_name
         , B.organization_id
         , B.organization_name
      FROM employees A 
        LEFT JOIN organizations B ON (A.organization_id = B.organization_id)

     WHERE 1 = 1
       AND B.organization_id = {ORGANIZATION_ID}
";

$organization_id = request()->organization_id;
$query = str_replace("{ORGANIZATION_ID}", $organization_id, $query);

Но это все еще не может использоваться в разбиении на страницы(). Есть хитрость, чтобы решить эту проблему. Смотреть ниже.

Окончательный код

Хитрость: поместите запрос внутрь (). Например: (SELECT * FROM TABLE_A).

Причина: функция paginage() создаст и выполнит запрос CountSELECT count(*) FROM (SELECT * FROM TABLE_A), если бы мы не заключили в скобки, запрос Count не был бы правильным запросом.

$query = "
    ( SELECT A.a_id
         , A.a_name
         , B.organization_id
         , B.organization_name
      FROM customers A 
        LEFT JOIN organizations B ON (A.organization_id = B.organization_id)
     WHERE 1 = 1
       AND B.organization_id = {ORGANIZATION_ID}

    UNION ALL

    SELECT A.a_id
         , A.a_name
         , B.organization_id
         , B.organization_name
      FROM employees A 
        LEFT JOIN organizations B ON (A.organization_id = B.organization_id)

     WHERE 1 = 1
       AND B.organization_id = {ORGANIZATION_ID}
    ) AS VIEW_RESULT
";

$organization_id = request()->organization_id;
$query = str_replace("{ORGANIZATION_ID}", $organization_id, $query);

$resultSet = DB::table(DB::raw($query))->paginate(20);

Теперь я могу использовать его нормально:

  1. ВЫБОР, ПРИСОЕДИНЕНИЕ, ОБЪЕДИНЕНИЕ
  2. разбиение на страницы
  3. Высокая производительность: Фильтрация данных перед получение

Надеюсь, это поможет!!!

 0
Author: Ngoc Nam, 2018-09-28 07:26:14
$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);
 -1
Author: tuan cao, 2017-04-20 04:22:15