date
е запазена дума
в стандартен SQL и името на тип данни в PostgreSQL. PostgreSQL го позволява като идентификатор, но това не го прави добра идея. Използвам thedate
вместо това като име на колона.
Не разчитайте на липсата на пропуски в заместващия ID. Това почти винаги е лоша идея. Третирайте такъв идентификатор като уникален номер без значение , дори ако изглежда, че носи определени други атрибути през повечето време .
В този конкретен случай, като @ Clodoaldo коментира
, date
изглежда перфектен първичен ключ и колоната id
е просто гаден - който премахнах:
CREATE TEMP TABLE tbl (thedate date PRIMARY KEY, rainfall numeric);
INSERT INTO tbl(thedate, rainfall) VALUES
('2002-05-06', 110.2)
, ('2002-05-07', 56.6)
, ('2002-05-09', 65.6)
, ('2002-05-10', 75.9);
Запитване
Пълна таблица по заявка:
SELECT x.thedate, t.rainfall -- rainfall automatically NULL for missing rows
FROM (
SELECT generate_series(min(thedate), max(thedate), '1d')::date AS thedate
FROM tbl
) x
LEFT JOIN tbl t USING (thedate)
ORDER BY x.thedate
Подобно на това, което @a_horse_with_no_name
публикуван, но опростен и пренебрегващ съкратения id
.
Попълва празнините между първата и последната дата, намерени в таблицата. Ако може да има водещи/изоставащи пропуски, разширете съответно. Можете да използвате date_trunc()
като @Clodoaldo
демонстрира - но заявката му страда от синтактични грешки и може да бъде по-проста.
ВМЪКНЕТЕ липсващи редове
Най-бързият и разбираем начин да го направите е NOT EXISTS
анти-полусъединяване.
INSERT INTO tbl (thedate, rainfall)
SELECT x.thedate, NULL
FROM (
SELECT generate_series(min(thedate), max(thedate), '1d')::date AS thedate
FROM tbl
) x
WHERE NOT EXISTS (SELECT 1 FROM tbl t WHERE t.thedate = x.thedate)