Laravel中多优先级排序问题咨询
解决多条件排序的问题
嘿,你的现有代码已经实现了按国家排序,要加上名字作为二级排序其实很简单,这里有两种靠谱的方法,你可以根据自己的场景选:
方法一:集合层面的多字段排序(延续你当前的写法)
Laravel的集合sortBy方法支持返回一个数组来定义多排序维度,先按数组里的第一个元素排序,当第一个元素相同时,自动按第二个元素排序。你只需要把闭包的返回值改成包含国家和名字的数组就行:
$students = User::with('user_profile') ->whereHas('roles', function($query){ return $query->where('slug', 'student'); }) ->get() ->sortBy(function($user){ // 先按国家排序,国家相同则按用户名字排序 return [$user->user_profile->country, $user->name]; });
方法二:数据库层面排序(性能更优)
如果你的学生数据量比较大,更推荐在数据库层面完成排序,这样不用把所有数据加载到PHP内存里再处理,性能会好很多。我们可以通过关联user_profiles表,然后用orderBy依次指定排序字段:
$students = User::with('user_profile') ->whereHas('roles', function($query){ return $query->where('slug', 'student'); }) ->join('user_profiles', 'users.id', '=', 'user_profiles.user_id') ->orderBy('user_profiles.country') ->orderBy('users.name') ->select('users.*') // 必须指定选择users表的所有字段,避免和user_profiles表的字段冲突 ->get();
注意这里的select('users.*')很重要,因为join之后如果两个表有同名字段(比如created_at),会导致数据覆盖,所以明确指定只取用户表的字段就没问题了。
内容的提问来源于stack exchange,提问作者Blues Clues
相关产品推荐
相关产品推荐

