您应该使用 groupby
。在查询生成器中,您可以这样做:
$users = DB::table('users')
->select('id','name', 'email')
->groupBy('name')
->get();
在 Eloquent 中,你也可以这样查询:
$users = User::select('name')->distinct()->get();
Note that I am not fetching that column only, it is in conjunction with other column values
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
雄辩地你可以使用这个
$users = User::select('name')->groupBy('name')->get()->toArray() ;
groupBy 实际上是获取不同的值,实际上 groupBy 将对相同的值进行分类,以便我们可以对它们使用聚合函数。但在这种情况下,我们没有聚合函数,我们只是选择会导致结果具有不同值的值
in_array()
函数检查项目是否存在,它永远不会工作。为了解决这个问题,我尝试了 ->lists()
(版本 5.2)。因此,$users = User::select('name')->groupBy('name')->lists('name');
对 php 的 in_array()
工作正常;
虽然我迟到了,但使用 Eloquent 获得不同记录的更好方法是
$user_names = User::distinct()->get(['name']);
get()
方法(我也测试过 first()
方法)来增加价值,这相当于使用 select()
方法如这里的一些答案所示。尽管不知何故 groupBy
似乎仍然得分最高。但是,如果这是我选择的唯一列,这将是真正不同的。
$user_names = User::distinct()->count(['name']);
也有效
**
经过 Laravel 5.8 测试
**
由于您想从表中获取所有列,您可以收集所有数据,然后使用名为 Unique 的 Collections 函数对其进行过滤
// Get all users with unique name
User::all()->unique('name')
或者
// Get all & latest users with unique name
User::latest()->get()->unique('name')
如需更多信息,您可以查看Laravel Collection Documentations
编辑:您可能会遇到性能问题,通过使用 Unique() 您将首先从 User 表中获取所有数据,然后 Laravel 将对其进行过滤。如果您有大量用户数据,这种方式并不好。您可以使用查询生成器并调用您想要使用的每个字段,例如:
User::select('username','email','name')->distinct('name')->get();
如果数据库规则不允许任何选择字段位于聚合函数之外,则分组依据将不起作用。而是使用 laravel collections。
$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;
});
如果您必须迭代大型集合,则为其添加一个键可以解决性能问题。
请注意,上面使用的 groupBy
不适用于 postgres。
使用 distinct
可能是更好的选择 - 例如 $users = User::query()->distinct()->get();
如果您使用 query
,您可以按要求选择所有列。
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
检索表中不同行的所有三个列。您可以根据需要添加任意数量的列。
我发现这种方法(对我来说)工作得很好,可以生成一个唯一值的平面数组:
$uniqueNames = User::select('name')->distinct()->pluck('name')->toArray();
如果您在此查询构建器上运行 ->toSql()
,您将看到它生成如下查询:
select distinct `name` from `users`
->pluck()
由Illumination\collection lib 处理(不是通过sql 查询)。
在尝试填充用户与其他用户拥有的所有唯一线程的列表时,我遇到了同样的问题。这对我有用
Message::where('from_user', $user->id)
->select(['from_user', 'to_user'])
->selectRaw('MAX(created_at) AS last_date')
->groupBy(['from_user', 'to_user'])
->orderBy('last_date', 'DESC')
->get()
// Get unique value for table 'add_new_videos' column name 'project_id'
$project_id = DB::table('add_new_videos')->distinct()->get(['project_id']);
以下是我测试过的 3 种方法,它们会给出相同的结果:
User::distinct()->get(['name'])->pluck('name');
User::select('name')->distinct()->pluck('name')->all();
DB::table('users')->select('name')->groupBy('name')->get()->pluck('name')->all();
对于那些像我一样犯同样错误的人。这是在 Laravel 5.7 中测试的详细答案
A. 数据库中的记录
UserFile::orderBy('created_at','desc')->get()->toArray();
Array
(
[0] => Array
(
[id] => 2073
[type] => 'DL'
[url] => 'https://i.picsum.photos/12/884/200/300.jpg'
[created_at] => 2020-08-05 17:16:48
[updated_at] => 2020-08-06 18:08:38
)
[1] => Array
(
[id] => 2074
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 17:20:06
[updated_at] => 2020-08-06 18:08:38
)
[2] => Array
(
[id] => 2076
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 17:22:01
[updated_at] => 2020-08-06 18:08:38
)
[3] => Array
(
[id] => 2086
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[created_at] => 2020-08-05 19:22:41
[updated_at] => 2020-08-06 18:08:38
)
)
B. 期望的分组结果
UserFile::select('type','url','updated_at)->distinct('type')->get()->toArray();
Array
(
[0] => Array
(
[type] => 'DL'
[url] => 'https://i.picsum.photos/12/884/200/300.jpg'
[updated_at] => 2020-08-06 18:08:38
)
[1] => Array
(
[type] => 'PROFILE'
[url] => 'https://i.picsum.photos/13/884/200/300.jpg'
[updated_at] => 2020-08-06 18:08:38
)
)
所以只传递 "select()"
中的那些列,它们的值是相同的。例如:'type','url'
。您可以添加更多列,前提是它们具有相同的值,例如 'updated_at'
。
如果您尝试在 "select()"
中传递 "created_at"
或 "id"
,那么您将获得与 A 相同的记录。因为它们对于 DB 中的每一行都是不同的。
where()
时它会中断,我该如何解决这个问题?group by
与distinct
不同。group by
将改变 SQL 查询中的count()
等聚合函数的行为。distinct
不会改变此类函数的行为,因此根据您使用的函数,您会得到不同的结果。