Как посчитать недостающие строки в левой таблице после правого соединения? - PullRequest
0 голосов
/ 26 января 2020

Существует две таблицы:

Таблица 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)
);

Я хочу найти показатели, по которым наибольшему количеству стран не хватает информации полностью, т. Е. Max (количество отсутствующих показателей по странам)

Я решил проблему в excel ( путем подсчета пробелов в сводной таблице по странам)

сводная таблица с подсчетом пропущенных показателей по странам

Я еще не определил наш запрос 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

Я пытался с кросс-соединение пока безуспешно.

Ответы [ 2 ]

0 голосов
/ 26 января 2020

Вам также нужно присоединиться к 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)
0 голосов
/ 26 января 2020

Я хочу найти показатели, по которым наибольшему количеству стран не хватает информации полностью, т. Е. Max (количество отсутствующих показателей по странам)

Это логическое противоречие. Счетчик пропущенных индикаторов по странам *

по странам

.. не может быть прикреплен к каким-либо указанным c индикаторам, поскольку эти страны не иметь показатель.

Подсчет по стране с «отсутствующим показателем» (т. е. 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 - это одна из четырех базовых c техник, которые применяются здесь (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 ограничение , чтобы запретить недействительные записи в education_data.indicator_id.

  • 2: установка education_data.indicator_id NOT NULL для запрета также пустых записей.
    или добавление PRIMARY KEY в (country_id, indicator_id) , что делает оба столбца NOT NULL автоматически.

.., что приближает вас к правильной реализации многие-ко-многим . См .:

...