PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL controlla l'elemento di un record precedente


Non funziona come hai tu. Una funzione finestra non si può chiamare così La tua variabile di record r è come un cursore integrato in un FOR ciclo continuo. Solo la riga corrente del risultato è visibile all'interno del ciclo. Dovresti integrare la funzione finestra lag() nel SELECT iniziale .

Ma dal momento che stai comunque scorrendo le righe in un ordine corrispondente, puoi farlo in un altro modo.

Considera questo esempio ampiamente riscritto. Ritorna alla prima riga in violazione:

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;

Altri suggerimenti

  • Perché l'alias per $1 ? L'hai chiamato _day già nella dichiarazione. Attieniti a questo.
  • Assicurati di sapere come PostgreSQL gestisce case in identificatori . (Uso solo lettere minuscole.)
  • Puoi semplicemente aggiungere/sottrarre numeri interi (per giorni) da una data.