date
is een gereserveerd woord
in standaard SQL en de naam van een gegevenstype in PostgreSQL. PostgreSQL staat het toe als identifier, maar dat maakt het geen goed idee. Ik gebruik thedate
in plaats daarvan als kolomnaam.
Vertrouw niet op de afwezigheid van hiaten in een surrogaat-ID. Dat is bijna altijd een slecht idee. Behandel zo'n ID als uniek nummer zonder betekenis , zelfs als het meestal bepaalde andere attributen lijkt te hebben .
In dit specifieke geval, als @ Clodoaldo heeft gereageerd
, thedate
lijkt een perfecte primaire sleutel te zijn en de kolom id
is gewoon cruft - die ik heb verwijderd:
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);
Zoekopdracht
Volledige tabel per zoekopdracht:
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
Vergelijkbaar met wat @a_horse_with_no_name
gepost, maar vereenvoudigd en negeert de gesnoeide id
.
Vult hiaten tussen de eerste en de laatste datum in de tabel in. Als er hiaten in de voor-/achteruitgang kunnen zijn, breid dan dienovereenkomstig uit. U kunt date_trunc()
. gebruiken zoals @Clodoaldo
gedemonstreerd - maar zijn vraag lijdt aan syntaxisfouten en kan eenvoudiger zijn.
VOEG ontbrekende rijen in
De snelste en meest leesbare manier om dit te doen is een 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)