PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Hinzufügen eines fehlenden Datums in einer Tabelle in PostgreSQL

date ist ein reserviertes Wort in Standard-SQL und der Name eines Datentyps in PostgreSQL. PostgreSQL erlaubt es als Bezeichner, aber das macht es nicht zu einer guten Idee. Ich verwende thedate stattdessen als Spaltenname.

Verlassen Sie sich nicht auf die Lückenfreiheit einer Ersatz-ID. Das ist fast immer eine schlechte Idee. Behandeln Sie eine solche ID als eindeutige Nummer ohne Bedeutung , auch wenn es meistens bestimmte andere Attribute zu tragen scheint .

In diesem speziellen Fall als @ Clodoaldo kommentierte , thedate scheint ein perfekter Primärschlüssel zu sein und die Spalte id ist nur Mist - den ich entfernt habe:

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);

Abfrage

Vollständige Tabelle nach Abfrage:

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

Ähnlich wie @a_horse_with_no_name gepostet, aber vereinfacht und ignoriert die gekürzte id .

Füllt Lücken zwischen dem ersten und letzten in der Tabelle gefundenen Datum. Wenn voreilende / nacheilende Lücken vorhanden sein können, erweitern Sie diese entsprechend. Sie können date_trunc() verwenden wie @Clodoaldo demonstriert - aber seine Abfrage leidet unter Syntaxfehlern und kann einfacher sein.

Fehlende Zeilen einfügen

Der schnellste und am besten lesbare Weg, dies zu tun, ist ein 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)