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

#mysql #database #laravel

#mysql #База данных #laravel

Вопрос:

Как выбрать последнюю из каждого option_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

Редактировать:

Просто для повторной итерации я хотел бы вернуть коллекцию latest option_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

Комментарии:

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

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

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

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

5. Table::select(DB::raw(‘max(created_at)’),’col1,col2,col3′))->groupby(‘option_id’)->distinct()->latest()->get() ; ? Попробуйте это?

Ответ №1:

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

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

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


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

Комментарии:

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

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

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

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

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

Ответ №2:

Если ваша таблица называется 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();
  

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

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

Ответ №3:

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

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