本文目录导读:

在 Laravel 中进行关联查询的排序和分组,有多种方法,以下是常用的几种方式:
关联查询排序
使用 orderBy 在关联查询中
// 一对多关联 - 根据关联表字段排序
$posts = Post::with(['comments' => function($query) {
$query->orderBy('created_at', 'desc');
}])->get();
// 根据关联表字段对主表排序
$posts = Post::with('user')
->join('users', 'posts.user_id', '=', 'users.id')
->orderBy('users.name', 'asc')
->select('posts.*')
->get();
使用 orderByRelation 方法
// 根据关联表的某个字段排序(Laravel 8.0+)
$posts = Post::orderBy('user.name')->get();
// 或者使用子查询
$posts = Post::orderByDesc(
User::select('name')->whereColumn('users.id', 'posts.user_id')
)->get();
关联查询分组
使用 groupBy 在关联查询中
// 按关联关系分组统计
$categories = Category::with(['posts' => function($query) {
$query->select('category_id', DB::raw('count(*) as post_count'))
->groupBy('category_id');
}])->get();
// 使用 withCount 统计关联数量
$categories = Category::withCount('posts')->get();
复杂场景示例
排序 + 分组 + 统计
// 查询每个分类下的文章数量,并按数量排序
$categories = Category::withCount('posts')
->having('posts_count', '>', 0)
->orderBy('posts_count', 'desc')
->get();
// 关联查询+条件+排序
$users = User::with(['orders' => function($query) {
$query->where('status', 'completed')
->orderBy('created_at', 'desc')
->limit(5);
}])->get();
// 多表关联分组统计
$products = Product::with(['orders' => function($query) {
$query->select('product_id', DB::raw('SUM(quantity) as total_quantity'))
->groupBy('product_id');
}])->get();
高级用法
使用 groupBy + orderBy 组合
// 按年份分组查询文章,并按年份排序
$postsByYear = Post::select('year', DB::raw('count(*) as total'))
->groupBy('year')
->orderBy('year', 'desc')
->get();
// 关联查询中的子查询排序(最有效的方法之一)
$users = User::select('users.*')
->addSelect(['latest_post_title' => Post::select('title')
->whereColumn('user_id', 'users.id')
->orderBy('created_at', 'desc')
->limit(1)
])
->get();
使用查询构建器
// 使用查询构建器进行复杂的关联分组
$results = DB::table('users')
->join('posts', 'posts.user_id', '=', 'users.id')
->select('users.id', 'users.name', DB::raw('COUNT(posts.id) as post_count'))
->groupBy('users.id', 'users.name')
->orderBy('post_count', 'desc')
->get();
注意事项
- 性能优化:使用
withCount比手动分组统计性能更好 - 索引优化:分组和排序的字段建议添加索引
- 缓存结果:频繁使用的查询可以缓存结果
- 索引优化:对于频繁的排序和分组字段,添加合适的索引
// 缓存查询结果
$cachedPosts = Cache::remember('posts_with_comments', 3600, function() {
return Post::with('comments')
->orderBy('created_at', 'desc')
->get();
});
选择哪种方法取决于你的具体需求,简单的场景用 with + orderBy,复杂统计用 withCount 或查询构建器。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播