有两个表:
表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
到目前为止,我已经尝试过交叉连接,但没有成功。
答案 0 :(得分:0)
我想找到最缺乏国家信息的指标,即完全缺乏信息的国家(即最大(按国家/地区缺少指标的数量)
这是一个逻辑矛盾。 ...
国家缺少指标的数量
..无法固定在任何特定指标上,因为这些国家/地区没有 指标。
带有“缺失指标”(即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
);
报告没有有效指标(无或无效)的国家/地区。
如果每个国家/地区都应该有一个有效的指标,请在清理现有数据后考虑:
1:添加FOREIGN KEY
constraint来禁止education_data.indicator_id
中的无效条目。
2:设置education_data.indicator_id NOT NULL
也禁止输入NULL。
或在(country_id, indicator_id)
上添加一个PRIMARY KEY
,这将自动使两个列都NOT NULL
。
..使您更接近有效的多对多实施。参见:
答案 1 :(得分:0)
您也必须加入contries
,否则您将无法确定contry是否在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)