Ответ 1
Вы должны использовать groupby
. В Query Builder вы можете сделать это следующим образом:
$users = DB::table('users')
->select('id','name', 'email')
->groupBy('name')
->get();
Это может быть довольно легко, но не знаю, как это сделать.
У меня есть таблица, которая может иметь повторяющиеся значения для определенного неквотного столбца. Как написать SQL-запрос с помощью Query Builder или Eloquent, который будет извлекать строки с различными значениями для этого столбца?
Обратите внимание, что я не получаю только этот столбец, он связан с другими значениями столбцов, поэтому distinct()
может не работать. Таким образом, в основном вопрос может заключаться в том, как указать столбец, который я хочу отличать в запросе, теперь distinct()
не принимает никаких параметров?
Вы должны использовать groupby
. В Query Builder вы можете сделать это следующим образом:
$users = DB::table('users')
->select('id','name', 'email')
->groupBy('name')
->get();
В Eloquent вы также можете запросить следующее:
$users = User::select('name')->distinct()->get();
вкратце вы можете использовать этот
$users = User::select('name')->groupBy('name')->get()->toArray() ;
groupBy фактически извлекает отдельные значения, на самом деле groupBy будет классифицировать одни и те же значения, чтобы мы могли использовать на них агрегатные функции. но в этом случае у нас нет агрегатных функций, мы просто выбираем значение, которое приведет к тому, что результат будет иметь различные значения
Хотя я опаздываю, чтобы ответить на этот вопрос, лучший подход к получению отдельных записей с использованием Eloquent будет
$user_names = User::distinct()->get(['name']);
Обратите внимание, что groupBy
, как указано выше, не будет работать для postgres.
Использование distinct
, вероятно, является лучшим вариантом - например.
$users = User::query()->distinct()->get();
Если вы используете query
, вы можете выбрать все столбцы в соответствии с запросом.
Группировка по не будет работать, если правила базы данных не позволяют ни одному из полей выбора находиться вне агрегатной функции. Вместо этого используйте коллекции laravel.
$users = DB::table('users')
->select('id','name', 'email')
->get();
foreach($users->unique('name') as $user){
//....
}
Кто-то отметил, что это не может быть большим по производительности для больших коллекций. Я бы порекомендовал добавить ключ в коллекцию. Используемый метод называется keyBy. Это простой метод.
$users = DB::table('users')
->select('id','name', 'email')
->get()
->keyBy('name');
KeyBy также позволяет добавить функцию обратного вызова для более сложных вещей...
$users = DB::table('users')
->select('id','name', 'email')
->get()
->keyBy(function($user){
return $user->name . '-' . $user->id;
});
Если вам приходится перебирать большие коллекции, добавление ключа к ним решает проблему производительности.
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
извлекает все три кулона для отдельных строк в таблице. Вы можете добавить столько столбцов, сколько пожелаете.
$users = Users::all()->unique('name');
Я обнаружил, что этот метод работает достаточно хорошо (для меня), чтобы создать плоский массив уникальных значений:
$uniqueNames = User::select('name')->distinct()->pluck('name')->toArray();
Если вы запустили ->toSql()
для этого построителя запросов, вы увидите, что он генерирует запрос, подобный следующему:
select distinct 'name' from 'users'
->pluck()
обрабатывается подсветкой \collection lib (не через SQL-запрос).