PHP项目Laravel关联查询排序与分组

wen PHP项目 3

本文目录导读:

PHP项目Laravel关联查询排序与分组

  1. 关联查询排序
  2. 关联查询分组
  3. 复杂场景示例
  4. 高级用法
  5. 使用查询构建器
  6. 注意事项

在 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 或查询构建器。

抱歉,评论功能暂时关闭!