SELECT date, region, COUNT(*) FROM file_stats fs, files f WHERE fs.file_id = f.id
GROUP BY date, region
не работает, так как не все регионы
represnted на все даты.
Предполагая, что вы имеете в виду, что он работает правильно, но вам нужны все даты, чтобы показать, может ли регион появиться там или нет, тогда вам нужны две вещи.
- Таблица календаря.
- Левое соединение в таблице календаря.
После того, как у вас есть календарь, что-то вроде этого. , .
SELECT c.cal_date, f.region, COUNT(*)
FROM calendar c
LEFT JOIN file_stats fs ON (fs.date = c.cal_date)
INNER JOIN files f ON (fs.file_id = f.id)
GROUP BY date, region
Я использовал cal_date выше. Имя, которое вы используете, зависит от вашей календарной таблицы. Это поможет вам начать. Вы можете использовать электронную таблицу для генерации дат.
CREATE TABLE calendar (cal_date date primary key);
INSERT INTO "calendar" VALUES('2011-01-01');
INSERT INTO "calendar" VALUES('2011-01-02');
INSERT INTO "calendar" VALUES('2011-01-03');
INSERT INTO "calendar" VALUES('2011-01-04');
INSERT INTO "calendar" VALUES('2011-01-05');
INSERT INTO "calendar" VALUES('2011-01-06');
INSERT INTO "calendar" VALUES('2011-01-07');
INSERT INTO "calendar" VALUES('2011-01-08');
Если вы уверены, что все даты указаны в file_stats, вы можете обойтись без таблицы календаря. Но есть некоторые предостережения.
select fs.date, f.region, count(*)
from file_stats fs
left join files f on (f.id = fs.file_id)
group by fs.date, f.region;
Это будет работать, если ваши данные верны, но ваши таблицы не гарантируют, что данные будут правильными. У вас нет ссылки на внешний ключ, поэтому в каждой таблице могут быть номера идентификаторов файлов, которые не совпадают с номерами идентификаторов в другой таблице. Давайте иметь некоторые примеры данных.
insert into files values (1, 'a long path', 'NYK');
insert into files values (2, 'another long path', 'NYK');
insert into files values (3, 'a shorter long path', 'LDN'); -- not in file_stats
insert into file_stats values ('2011-01-01', 1, 35);
insert into file_stats values ('2011-01-02', 1, 37);
insert into file_stats values ('2011-01-01', 2, 40);
insert into file_stats values ('2011-01-01', 4, 35); -- not in files
Выполнение этого запроса (аналогично приведенному выше, но добавьте ORDER BY). , .
select fs.date, f.region, count(*)
from file_stats fs
left join files f on (f.id = fs.file_id)
group by fs.date, f.region
order by fs.date, f.region;
. , , возвращает
2011-01-01||1
2011-01-01|NYK|2
2011-01-02|NYK|1
'LDN' не отображается, потому что в file_stats нет строки с идентификатором файла № 3. Одна строка имеет нулевую область, потому что ни одна строка в файлах не имеет идентификатора файла № 4.
Вы можете быстро найти несовпадающие строки с помощью левого соединения.
select f.id, fs.file_id
from files f
left join file_stats fs on (fs.file_id = f.id)
where fs.file_id is null;
возвращает
3|
означает, что в файлах есть строка с идентификатором 3, но в file_stats нет строки с идентификатором 3. Переверните таблицу, чтобы определить строки в file_stats, у которых нет совпадающей строки в файлах.
select fs.file_id, f.id
from file_stats fs
left join files f on (fs.file_id = f.id)
where f.id is null;