Ne fonctionne pas comme vous l'avez. Une fonction de fenêtre
ne peut pas être appelé comme ça. Votre variable d'enregistrement r
est comme un curseur intégré dans un FOR
boucle. Seule la ligne courante du résultat est visible à l'intérieur de la boucle. Il faudrait intégrer la fonction window lag()
dans le SELECT
initial .
Mais puisque vous parcourez de toute façon les lignes dans un ordre correspondant, vous pouvez le faire d'une autre manière.
Considérez cet exemple largement réécrit. Renvoie à la première ligne non conforme :
CREATE OR REPLACE FUNCTION q8(_day date)
RETURNS text AS
$BODY$
DECLARE
r record;
last_enddate date;
BEGIN
FOR r IN
SELECT *
-- ,lag(r.endDate) OVER (ORDER BY startDate) AS last_enddate
-- commented, because I supply an alternative solution
FROM periods
ORDER BY startDate
LOOP
IF _day BETWEEN r.startDate AND r.endDate THEN
RETURN 'Violates condition 1'; -- I return differing results
ELSIF _day BETWEEN (r.startDate - 7) AND r.startDate THEN
RETURN 'Violates condition 2';
ELSIF _day BETWEEN last_enddate AND (r.startDate) THEN
-- removed "- 7 ", that is covered above
RETURN 'Violates condition 3';
END IF;
last_enddate := r.enddate; -- remember for next iteration
END LOOP;
RETURN NULL;
END;
$BODY$ LANGUAGE plpgsql;
Plus d'astuces
- Pourquoi l'alias pour
$1
? Vous l'avez nommé_day
déjà dans la déclaration. Tenez-vous-y. - Assurez-vous de savoir comment PostgreSQL gère cas dans les identifiants . (Je n'utilise que des minuscules.)
- Vous pouvez simplement ajouter/soustraire des nombres entiers (pour les jours) d'une date.