PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

ajouter une date manquante dans une table dans PostgreSQL

date est un mot réservé en SQL standard et le nom d'un type de données dans PostgreSQL. PostgreSQL l'autorise comme identifiant, mais cela n'en fait pas une bonne idée. J'utilise thedate comme nom de colonne à la place.

Ne vous fiez pas à l'absence de lacunes dans un ID de substitution. C'est presque toujours une mauvaise idée. Traiter un tel identifiant comme un numéro unique sans signification , même s'il semble porter certains autres attributs la plupart du temps .

Dans ce cas particulier, comme @ Clodoaldo a commenté , thedate semble être une clé primaire parfaite et la colonne id est juste cru - que j'ai supprimé :

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

Requête

Tableau complet par requête :

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

Semblable à ce que @a_horse_with_no_name posté, mais simplifié et en ignorant le id élagué .

Comble les lacunes entre la première et la dernière date trouvées dans le tableau. S'il peut y avoir des écarts en avance / en retard, étendez-les en conséquence. Vous pouvez utiliser date_trunc() comme @Clodoaldo démontré - mais sa requête souffre d'erreurs de syntaxe et peut être plus simple.

INSÉRER les lignes manquantes

Le moyen le plus rapide et le plus lisible de le faire est un NOT EXISTS anti-semi-jointure.

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)