PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

aggiungendo la data mancante in una tabella in PostgreSQL

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)