sql >> Databasteknik >  >> RDS >> PostgreSQL

lägga till saknat datum i en tabell i PostgreSQL

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)


  1. Infoga skrapad tabelldata direkt i PostgreSQL db

  2. Använder Kubernetes för att distribuera PostgreSQL

  3. mysql:Hämta senaste konversationsposter av användare

  4. DBD::Oracle-installationen orsakar fel