У меня есть модель Post, и я пытаюсь ->paginate() , ->groupBy() и ->orderBy() .
public function index() { $posts = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->paginate(5); // dd($posts); }поpublic function index() { $posts = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->paginate(5); // dd($posts); }
Между тем данные в базе данных выглядят следующим образом:
| id | verified | topic | publisher_id | body | created_at | | 25 | 1 | Forest | 3 | EE | 10.12.50 | | 24 | 1 | Forest | 3 | DD | 10.11.40 | | 23 | 1 | Forest | 3 | CC | 10.10.30 | | 22 | 1 | Dance | 2 | BB | 9.50.50 | | 21 | 1 | Dance | 2 | AA | 9.40.40 | | 20 | 1 | Music | 1 | ZZ | 9.30.30 | | 19 | 1 | Music | 1 | XX | 9.20.20 | | 18 | 1 | Art | 1 | YY | 9.10.10 | | 17 | 1 | Art | 1 | WW | 9.00.00 | | 16 | 1 | Ski | 2 | KK | 7.00.00 |
Когда я раскомментирую dd() и запускаю код, я получаю этот журнал:
LengthAwarePaginator { ... items : { items : { 0 => Post{..} 1 => Post{..} 2 => Post{..} 3 => Post{..} ... } } ... }
0 => Post{#249} : "published_by: "3", "body": "CC", "created_at": "10.10.30"
1 => Post{#250} : "published_by: "1", "body": "XX", "created_at": "9.20.20"
2 => Post{#251} : "published_by: "1", "body": "WW", "created_at": "9.00.00"
3 => Post{#252} : "published_by: "2", "body": "KK", "created_at": "7.00.00"
Это выглядит странно по какой-то причине. Он сделал groupBy для пользователя-3, но не для других. Кроме того, он потянет самое раннее, созданное, а не последнее. Изменение desc to asc like ->orderBy('created_at', 'asc') полностью вывело бы из строя.
Другими словами, возвращая 'CC' for user-3, Forest вместо 'EE' for user-3, Forest
Тогда я подумал, что, возможно, это ->paginate(5) .
public function post() { $posts = Post::where... ... ->paginate(5); $postsTry = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->get(); // dd($postsTry); }поpublic function post() { $posts = Post::where... ... ->paginate(5); $postsTry = Post::where('verified', '1') ->orderBy('created_at','desc') ->groupBy('topic', 'publisher_id') ->get(); // dd($postsTry); }
Я получаю коллекцию только с такими items как над ним. ( 0 => Post{..}, 1 => Post{..}, 2 => Post{..} ).
Он группирует данные как самые ранние сначала, а не последние сначала . Что мне не хватает? Что я делаю неправильно?
Чтобы завершить, обратите внимание, что я хочу получить:
'EE' for user-3, Forest
'BB' for user-2, Dance
'ZZ' for user-1, Music
'YY' for user-1, Art
Убрал мой предыдущий ответ, но все равно будет включать примечание от Laravel Pagination о groupBy() с помощью paginate() .
Примечание. В настоящее время операции с
groupByпоgroupByкоторые используют операторgroupByне могут эффективно выполняться Laravel. Если вам нужно использоватьgroupByсgroupByна страницы набором результатов, рекомендуется запросить базу данных и создать файл-указатель вручную.
ОБНОВИТЬ
Из-за вашего необычного формата даты для поля created_at вам понадобятся целочисленные значения cast ed, которые будут использоваться правилом order by statement (как целое, а не строка). Вот рабочий пример:
Post::selectRaw("*, CAST(REPLACE(created_at, '.', '') AS UNSIGNED INTEGER) ca") ->where('verified', '1') ->orderBy('ca', 'desc') ->groupBy('topic', 'publisher_id') ->paginate();
Вам нужно будет использовать подзапрос (или другой метод соединения), чтобы получить верхний элемент в вашей группе. См. Раздел « Получение строк», удерживающих групповой максимум определенного столбца
Удалил мой пример.