这可能很容易,但不知道如何做。
我有一个表,可以为特定的非关键列字段重复值。如何使用查询生成器或Eloquent编写SQL查询,以获取该列具有不同值的行?
请注意,我并不是仅获取该列,而是将其与其他列值结合使用,因此distinct()
可能无法真正使用。因此,这个问题基本上可以是如何指定现在不distinct()
接受任何参数的查询中要区分的列?
Answers:
您应该使用groupby
。在查询生成器中,您可以按照以下方式进行操作:
$users = DB::table('users')
->select('id','name', 'email')
->groupBy('name')
->get();
where()
中断时,该如何解决?
group by
与并不相同distinct
。group by
将更改聚合函数的行为,例如count()
在SQL查询内部。distinct
不会改变此类功能的行为,因此您会根据使用哪种功能而获得不同的结果。
在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();
->orderBy('name')
,如果你想使用这项功能chunk
。
雄辩的你可以用这个
$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集合。
$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;
});
如果必须遍历大型集合,则向其添加密钥可以解决性能问题。
**
**
由于您想从表中获取所有列,因此您可以收集所有数据,然后使用称为“唯一”的“收集”功能对其进行过滤
// Get all users with unique name
User::all()->unique('name')
要么
// Get all & latest users with unique name
User::latest()->get()->unique('name')
有关更多信息,您可以查看Laravel Collection文档
编辑:您可能对性能有问题,通过使用Unique(),您将首先从User表中获取所有数据,然后Laravel将对其进行过滤。如果您有大量的用户数据,这种方法不好。您可以使用查询生成器并调用要使用的每个字段,例如:
User::select('username','email','name')->distinct('name')->get();
尝试填充用户与其他用户的所有唯一线程的列表时,我遇到了相同的问题。这对我有用
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()
对于喜欢我的人犯同样的错误。这是在Laravel 5.7中测试的详尽答案
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
)
)
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'
。
如果您尝试通过"created_at"
或"id"
in "select()"
,那么您将获得与A相同的记录。因为它们在DB中的每一行都是不同的。