date
è una parola riservata
in SQL standard e il nome di un tipo di dati in PostgreSQL. PostgreSQL lo consente come identificatore, ma ciò non lo rende una buona idea. Uso thedate
come nome della colonna invece.
Non fare affidamento sull'assenza di lacune in un ID surrogato. È quasi sempre una cattiva idea. Tratta tale ID come numero univoco senza significato , anche se sembra avere alcuni altri attributi il più delle volte .
In questo caso particolare, come @ ha commentato Clodoaldo
, thedate
sembra essere una chiave primaria perfetta e la colonna id
è solo cruft - che ho rimosso:
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);
Interrogazione
Tabella completa per query:
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
Simile a quello che @a_horse_with_no_name
pubblicato, ma semplificato e ignorando l'id
potato .
Riempie gli spazi tra la prima e l'ultima data presenti nella tabella. Se possono esserci spazi vuoti in anticipo/ritardo, estendere di conseguenza. Puoi usare date_trunc()
come @Clodoaldo
dimostrato - ma la sua query soffre di errori di sintassi e può essere più semplice.
INSERIRE le righe mancanti
Il modo più veloce e leggibile per farlo è un NOT EXISTS
anti-semi-unione.
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)