date
är ett reserverat ord
i standard SQL och namnet på en datatyp i PostgreSQL. PostgreSQL tillåter det som identifierare, men det gör det inte till en bra idé. Jag använder thedate
som kolumnnamn istället.
Lita inte på frånvaron av luckor i ett surrogat-ID. Det är nästan alltid en dålig idé. Behandla ett sådant ID som unikt nummer utan mening , även om den verkar ha vissa andra attribut för det mesta .
I det här specifika fallet, som @ Clodoaldo kommenterade
, thedate
verkar vara en perfekt primärnyckel och kolumnen id
är bara cruft - som jag tog bort:
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);
Fråga
Fullständig tabell efter fråga:
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
Liknar vad @a_horse_with_no_name
postat, men förenklat och ignorerar det beskärda id
.
Fyller i luckor mellan första och sista datum som finns i tabellen. Om det kan finnas ledande/eftersläpande luckor, utöka därefter. Du kan använda date_trunc()
gillar @Clodoaldo
visat - men hans fråga lider av syntaxfel och kan vara enklare.
INSERT saknade rader
Det snabbaste och mest läsbara sättet att göra det på är en NOT EXISTS
anti-semi-join.
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)