Как выбрать последние записи каждого значения с помощью Eloquent?

Как выбрать последний из каждого option_id user_id?

+-----+-----------+---------+-------+
| id  | option_id | user_id | value |
+-----+-----------+---------+-------+
| 241 |         6 |       2 |     2 |
| 240 |         5 |       2 |     1 |
|  90 |         5 |       2 |    15 |
|  75 |         4 |       2 |    11 |
|  76 |         4 |       2 |     1 |
|  77 |         4 |       2 |     2 |
|  72 |         4 |       1 |    10 |
|  71 |         4 |       1 |    15 |
|  70 |         5 |       1 |     2 |
+-----+-----------+---------+-------+

Как написать запрос, используя Eloquent, чтобы получить только последний из каждого option_id данного user_id?

Для предоставленной таблицы вывод для user_id 2 должен быть идентификатором записи: 241,240,75.

Для записей user_id 1: 72, 70

Обновлено:

Просто чтобы повторить итерацию, я хотел бы вернуть коллекцию последних option_id для данного user_id.

Поэтому для user_id 2 будет 3 записи:

  • идентификатор записи 241, который содержит последнее значение для option_id 6
  • идентификатор записи 240, который содержит последнее значение для option_id 5
  • идентификатор записи 75, который содержит последнее значение для option_id 4

Для user_id 1 будет только 2 записи:

  • идентификатор записи 72, который содержит последнее значение для option_id 4
  • идентификатор записи 70, который содержит последнее значение для option_id 5

Можете ли вы объяснить, что вы спрашиваете? Последняя запись для user_id 2 имеет идентификатор 76. Непонятно, что вы хотите выбрать.

MrMoxy 09.04.2019 17:05

Что это за модель?

thisiskelvin 09.04.2019 17:05

@MrMoxy Пользователь 2 имеет записи для option_id 4, 5 и 6. И ему в основном нужна самая новая запись для каждого option_id.

Thomas 09.04.2019 17:10

@ Томас, это именно то, что я хочу. Спасибо

Domatorov 09.04.2019 17:19

Table::select(DB::raw('max(created_at)'),'col1,col2,col3'))-‌​>groupby('option_id'‌​)->distinct()->опоздания‌​t( )->получить(); ? Попробуй это?

Lim Kean Phang 09.04.2019 18:21

@LimKeanPhang извините, бесполезно, у меня нет столбца created_at. Это будет самый высокий идентификатор, который можно использовать для определения идентификатора новейшей опции.

Domatorov 09.04.2019 18:26

Table::select(DB::raw('max(id)'),'col1,col2,col3'))->groupby‌​('option_id')->disti‌​nct()->latest()-> получить‌(); //Возможно, максимальный идентификатор? Согласно вашему заявлению выше

Lim Kean Phang 09.04.2019 18:30

Но 77 является «последним» значением опции для user_id 2, option_id 4. MySQL не может выбирать на основе позиции или порядка записи в таблицу, только на основе значений.

MrMoxy 09.04.2019 19:54
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
8
350
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Предполагая, что таблица является пользовательской, и учитывая, что $id является динамическим. Может ты имеешь в виду вот это:

$user = User::where('user_id', $id) 
            ->orderBy('id', 'DESC') 
            ->get();

И, наконец, используйте этот код $user->unique('option_id'), чтобы получить фактический результат.


Hope it helps :)

Привет, выбран последний идентификатор, а не последний идентификатор каждого option_id.

Domatorov 09.04.2019 17:27

@JDoe, вы имеете в виду получение последней записи на основе option_id? Я сделал правку, не могли бы вы проверить.

schutte 09.04.2019 17:32

Боюсь, это не то, чего я хотел. Я добавил описание к своему вопросу. В основном я хочу вернуть самый высокий (последний/самый новый) из каждого option_id (всего одну запись) для user_id 2, например. Учитывая, что есть 6 option_id, я ожидаю, что 6 записей будут возвращены только с последними значениями.

Domatorov 09.04.2019 17:41

@JDoe, не могли бы вы попробовать мой отредактированный код. Я думаю, это сработает

schutte 09.04.2019 18:05

спасибо, но ничего хорошего, ваше решение возвращает коллекцию всех option_id, а не только последние.

Domatorov 09.04.2019 18:05

@JDoe, братан, можешь попробовать обновленный пост. и дайте мне знать проблему.

schutte 11.04.2019 15:59

Если ваша таблица называется user_options, вот запрос Eloquent для выбора записей, которые вы ищете.

        $getValues = DB::table('user_options')
        ->join(DB::raw('(SELECT max(user_options.id) FROM user_options INNER JOIN (
                        SELECT option_id, user_id FROM user_options GROUP BY option_id, user_id) sets
                        WHERE user_options.option_id = sets.option_id AND user_options.user_id = sets.user_id
                        GROUP BY user_options.option_id, user_options.user_id
            ) valuerecords'),
        function($join)
        {
           $join->on('user_options.id', '=', 'valuerecords.id');
        })->select(
            'id',
            'option_id',
            'user_id',
            'value'
        )->get();

Необработанный запрос на выборку получает идентификаторы последних записей, а затем присоединяется к таблице для получения записей.

Обратите внимание, что «последняя» запись — это запись с самым высоким идентификатором, поэтому она захватит запись 77, а не 75. Если вы определяете последнюю по-другому, вы можете соответствующим образом изменить необработанный запрос.

Ответ принят как подходящий

Оказывается, это было так просто:

      $options= DB::table('options')
            ->where('user_id', Auth::getUser()->id)
            ->groupBy("option_id")
            ->orderBy("option_id", "DESC")
            ->get();

Но пришлось установить строгий режим на false для этого запроса и вернуть его на true после извлечения данных.

Перед запросом:


        // turn off strict mode for the below query
        config()->set('database.connections.mysql.strict', false);
        \DB::reconnect(); //important as the existing connection if any would be in strict mode

и после запроса:

        //now changing back the strict ON
        config()->set('database.connections.mysql.strict', true);
        \DB::reconnect();

Другие вопросы по теме