【问题标题】:How to prevent query from removing 'null' records如何防止查询删除“空”记录
【发布时间】:2017-10-23 20:23:44
【问题描述】:

这里有 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 的顺序结果不一样。

【问题讨论】:

  • 添加一些示例表数据和预期结果 - 作为格式化文本,而不是图像。
  • 替换你的????与左外
  • @jarlh : 我刚刚编辑了我的问题
  • 预期结果很好,但我们还需要知道用于获得该结果的表数据。
  • 出于隐私原因,我不能拥有这个(我的问题使用了模拟模式)。

标签: sql database join


【解决方案1】:

您应该先查询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

【讨论】:

  • ...鉴于想要的现有结果集,CROSS JOIN 几乎可以肯定是正确答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多