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)