【问题标题】:How to count missing rows in left table after right join?右连接后如何计算左表中丢失的行?
【发布时间】:2020-05-12 02:10:41
【问题描述】:

有两个表:

education_data(按衡量指标按年份列出的国家/地区列表)。

create table education_data 
(country_id int,
indicator_id int,
year date,
value float
);

表格indicators(所有指标列表):

create table indicators
(id int PRIMARY KEY,
name varchar(200),
code varchar(25)
);

我想找出完全缺乏信息的国家数量最多的指标 即最大值(按国家/地区列出的缺失指标计数)

我已经在 excel 中解决了这个问题(通过按国家/地区计算数据透视表中的空白)

pivot table with count for missing indicators by country

我还没有想到我们的 SQL 查询会返回相同的结果。

我能够返回某个国家/地区缺失指标的数量,请阅读下面的查询,但不是针对所有国家/地区。

SELECT COUNT(*)
FROM education_data AS edu
RIGHT JOIN indicators AS ind ON
edu.indicator_id = ind.id and country_id = 10 
WHERE value IS NULL 
GROUP BY country_id

到目前为止,我已经尝试过交叉连接但没有成功。

【问题讨论】:

  • 你有国家表吗?
  • @clamp 是的,我愿意。

标签: sql postgresql join count left-join


【解决方案1】:

你也必须加入contries,否则你无法判断一个国家是否在education_data中没有条目:

create table countries(id serial primary key, name varchar);
create table indicators
(id int PRIMARY KEY,
name varchar(200),
code varchar(25)
);
create table education_data 
(country_id int references countries,
indicator_id int references indicators,
year date,
value float
);

insert into countries values (1,'USA');
insert into countries values (2,'Norway');
insert into countries values (3,'France');
insert into indicators values (1,'foo','xxx');
insert into indicators values (2,'bar', 'yyy');
insert into education_data  values(1,1,'01-01-2020',1.1);

SELECT count (c.id), i.id, i.name
FROM countries c JOIN indicators i ON (true) LEFT JOIN education_data e ON(c.id = e.country_id AND i.id = e.indicator_id) 
WHERE indicator_id IS NULL
GROUP BY i.id;


count | id | name 
-------+----+------
     3 |  2 | bar
     2 |  1 | foo
(2 rows)

【讨论】:

  • 完全正确。这是正确的答案。如果我想添加另一个条件:只有具有 c.is_country 字段 =True 的国家/地区,我将如何更改左外连接?
  • 您可以将其添加到WHERE 子句或(第一个)JOIN 条件中。
  • 我只是想仔细检查一下。谢谢。这个问题并不难,但我的突触已经烧坏了。
【解决方案2】:

我想找到完全缺乏信息的国家数量最多的指标,即最大值(按国家/地区的缺失指标计数)

这是一个逻辑矛盾。 ...

按国家/地区列出的缺失指标计数

.. 不能固定在任何特定指标上,因为这些国家/地区没有指标。

每个国家的“缺失指标”计数(即indicator_id IS NULL

SELECT country_id, count(*) AS ct_indicator_null
FROM   education_data
WHERE  indicator_id IS NULL
GROUP  BY country_id
ORDER  BY count(*) DESC;

或者,更一般地说,没有有效指示符,其中还包括indicator_id 在表indicators 中没有匹配的行:

SELECT country_id, count(*) AS ct_no_valid_indicator
FROM   education_data e 
WHERE  NOT EXISTS (
   SELECT FROM indicators i
   WHERE  i.id = e.indicator_id
   )
GROUP  BY country_id
ORDER  BY count(*) DESC;

NOT EXISTS 是适用于此处的四种基本技术之一(LEFT / RIGHT JOIN,就像您尝试成为另一种技术一样)。见:

您提到了country 表。 education_data 中没有任何指标条目的国家不包括在上述结果中。也可以找到这些:

SELECT *
FROM   country c
WHERE  NOT EXISTS (
   SELECT
   FROM   education_data e
   JOIN   indicators     i ON i.id = e.indicator_id  -- INNER JOIN this time!
   WHERE  e.country_id = c.id
   );

报告没有有效指示符的国家/地区(无或无效)。


如果每个国家都应该有一个有效的指标,在​​清理现有数据后,考虑:

.. 这使您更接近有效的多对多实现。见:

【讨论】:

  • 感谢您的详尽解释和链接。
猜你喜欢
  • 1970-01-01
  • 2020-05-10
  • 2021-12-16
  • 2013-07-12
  • 2013-12-05
  • 2018-01-21
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多