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) запрос работает нормально.
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'));
Я уже сталкивался с подобной проблемой. Я нашел тему также не о 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)
. (но вам придется немного раскошелиться, чтобы соответствовать вашей проблеме)
Заказать по
$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
Его помощь большему числу народов.. потому что никто не может понять, как отображать данные в объединении страниц просмотра с разбиением на страницы и порядком.. спасибо вам
У меня была та же проблема, и, к сожалению, я не смог получить ссылки на страницы с помощью {{ $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]);
Я знаю, что этот ответ слишком запоздал. Но я хочу поделиться своими проблемами и своим решением.
Мои проблемы:
- Объединяйтесь со многими таблицами одновременно
- ОБЪЕДИНЕНИЕ
- Разбиение на страницы (Должно использоваться, потому что я должен использовать общую тему для отображения разбиения на страницы. Если я сделал собственный обычай для разбиения на страницы, он не будет соответствовать текущему. И в будущем общая тема может быть изменена.)
- Большие данные: просмотр занял 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);
Теперь я могу использовать его нормально:
- ВЫБОР, ПРИСОЕДИНЕНИЕ, ОБЪЕДИНЕНИЕ
- разбиение на страницы
- Высокая производительность: Фильтрация данных перед получение
Надеюсь, это поможет!!!
$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);