以下是3个表格:
城市( id PK ,姓名,邮政编码)
职位( id PK ,职称)
人员( id PK ,first_name,last_name, job_id FK职位, city_id FK城市)
每个人都有工作,住在城市,城市和工作岗位都至少有0人(0..n)。
我想计算每个工作和城市的人数而不去除没有人的城市和工作:
> +----------+----------+---------------+
| city_id | job_id | count(p.id) |
+------------+----------+---------------+
| 140 | 1 | 0 |
| 249 | 37 | 1 |
| 249 | 40 | 1 |
| 249 | 269 | 1 |
| 250 | 4823 | 3 |
| 251 | 1 | 4 |
| 251 | 205 | 1 |
| 433 | 1 | 0 |
| 433 | 40 | 1 |
| 433 | 23 | 1 |
| 433 | 1346 | 1 |
| 434 | 5 | 5 |
| 434 | 70 | 1 |
| 434 | 5332 | 1 |
我猜查询应该是这样的:
SELECT job_id, city_id, COUNT(p.id)
FROM persons p
???? JOIN jobs j ON p.job_id=j.id
???? JOIN cities c ON p.city_id=c.id
GROUP BY j.id, c.id
我知道使用INNER JOIN无法完成,因为所有不包含连接引用的行都将被忽略。
我尝试了RIGHT JOIN,但依赖于JOIN的订单结果不一样。
答案 0 :(得分:0)
您应该先使用cities
然后jobs
开始查询,然后计算一些人。但是在您的数据库模式中,由于没有链接城市和工作,因此很难有效地完成工作。处理它的最好方法是改变你的数据库模式:
cities(id PK, name, zipcode)
jobs(id PK, title, city_id FK cities)
persons(id PK, first_name, last_name, job_id FK jobs)
您可以看到差异 - 工作与城市相关联,某个人与工作相关联,而工作又与该工作所在的城市相关联。
如果您按照这种方式,您可以编写如下查询:
select c.id as city_id, j.id as job_id, count(p.id)
from cities c
inner join jobs j on (j.city_id = c.id)
left outer join persons p on p.job_id = j.id
group by c.id, j.id
但是,如果您保留现有架构,则需要在城市和工作之间进行交叉连接,这可能效率低下并产生噪音结果(某些城市中没有的工作)。您需要此查询:
select c.id as city_id, j.id as job_id, count(p.id)
from cities c
cross join jobs j
left outer join persons p on (p.job_id = j.id) and (j.city_id = c.id)
group by c.id, j.id