首页 > 解决方案 > 具有多个连接的 Laravel GroupBy

问题描述

我在三向连接中获取正确数据时遇到问题。

编辑:示例表结构

Jobs Table

id | name     | country      | country_slug  | city

1  | Job1     | Canada       | canada        | Ontario

2  | Job2     | South Africa | south-africa  | Durban

Cheers Table

id |  rep  | jobs_id

1  |  14   | 2

2  |  9    | 1

3  |  12   | 2

4  |  23   | 1
Categories Table

id |  name  

1  |  PHP   

2  |  Laravel 

3  |  Javascript 

4  |  Go

category_job pivot Table

id |  category_id | job_id  

1  |  2           | 1

2  |  2           | 2

3  |  1           | 1

4  |  3           | 2

5  |  4           | 1

这是我的模型的示例:

Job

public function categories(){
   $this->belongsToMany(Category::class)
}


public function cheers(){
   $this->hasMany(Cheer::class)
}
Category

public function jobs() {
   $this->belongsToMany(Job::class)
}

Cheer

public function job() {
  return $this->belongsTo(Job::class);
}

这就是我想要实现的目标:

  1. 按国家/地区分组工作
  2. 计算每个国家有多少工作(job_count)
  3. 计算每组中有多少个城市(不同)(city_count)
  4. 每个组的欢呼关系表中的总和(代表)
  5. 通过类别关系获取每个国家/地区组最受欢迎的类别

到目前为止,这是我的代码:

      $result = Job::
            selectRaw(
            "jobs.country,
                            jobs.country_slug,
                            COUNT('jobs') as job_count,
                            COUNT(DISTINCT city) as city_count,
                            SUM(rep) as cheer_rep",
        )
            ->join('cheers', 'cheers.jobs_id', '=', 'jobs.id')
            ->orderByDesc('cheer_rep')
            ->groupBy('jobs.country', 'jobs.country_slug')
            ->get();

这是我的问题;

  1. 作业计数是错误的,因为由于 hasMany 关系,join 子句添加了更多结果。
  2. 我似乎无法集中精力对类别进行分组并获得最常见(流行)的类别。
Sample result
[
  {
    "country": "Canada",
    "country_slug": "canada",
    "job_count": 23,
    "cities": 5,
    "cheer_rep": "35000"
  },
  {
    "country": "South Africa",
    "country_slug": "south-africa",
    "job_count": 9,
    "cities": 2,
    "cheer_rep": "700"
  },
]

任何帮助将不胜感激。另外,如果有一种雄辩的方式来实现这一点,我也会很感激。

标签: phplaravel

解决方案


口才方式:

Job::with('cheers')
->select(DB::raw('count(country) as job_count, country'), 
         DB::raw('count(city) as city_count, city')
)
->orderByDesc('cheers.cheer_rep')
->groupBy('country', 'country_slug')
->get();

注意:未测试,因为您没有提供数据库架构。


推荐阅读