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

Differenza di data PostgreSQL

Debug

Quello che sta facendo la tua funzione potrebbe essere fatto molto più semplice. La vera causa dell'errore di sintassi è qui:

SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;

Sembra che tu stia tentando di trasmettere startDate a timestamp , che è una sciocchezza all'inizio, perché il tuo parametro startDate è dichiarato come timestamp già.

Inoltre non funziona. Cito il manuale qui :

lo farebbe funziona così:

SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;

Ma ancora non avrebbe molto senso. Stai parlando di "date", ma definisci comunque i tuoi parametri come timestamp . Potresti igienizza quello che hai in questo modo:

CREATE OR REPLACE FUNCTION f_date_diff()
  RETURNS int AS
$BODY$
DECLARE
    start_date date;
    end_date   date;
    date_diff  int;
BEGIN
SELECT evt_start_date FROM events WHERE evt_id = 5 INTO start_date;
SELECT evt_start_date FROM events WHERE evt_id = 6 INTO end_date;
date_diff := (endDate - startDate);
RETURN date_diff;
END
$BODY$ LANGUAGE plpgsql;
  • DECLARE necessario solo una volta.
  • date colonne dichiarate come corrette di tipo date .
  • Non utilizzare identificatori di casi misti, a meno che tu non sappia esattamente cosa stai facendo.
  • Sottrai l'inizio dalla fine per ottenere un numero positivo o applicare l'operatore di valore assoluto @ .
  • Dal momento che sottraendo date (invece di sottrarre timestamp , che restituisce un interval ) restituisce già integer , semplifica in:

    SELECT (startDate - endDate) INTO diffDatePart;
    

    O ancora più semplice come assegnazione plpgsql:

    diffDatePart := (startDate - endDate);
    

Richiesta semplice

Puoi risolvere il semplice compito con una semplice query, utilizzando una sottoquery:

SELECT (SELECT evt_start_date
        FROM   events
        WHERE  evt_id = 6) 
      - evt_start_date AS date_diff
FROM   events
WHERE  evt_id = 5;

Oppure potresti CROSS JOIN la tabella di base a se stessa (1 riga da ogni istanza, quindi va bene):

SELECT e.evt_start_date - s.evt_start_date AS date_diff
FROM   events e
      ,events s
WHERE  e.evt_id = 6
AND    s.evt_id = 5;

Funzione SQL

Se insisti su una funzione allo scopo, usa una semplice funzione sql:

CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
  RETURNS int LANGUAGE sql AS
$func$
SELECT e.evt_start_date - s.evt_start_date
FROM   events s, events e
WHERE  s.evt_id = $1
AND    e.evt_id = $2
$func$;

Chiama:

SELECT  f_date_diff(5, 6);

Funzione PL/pgSQL

Se insisti su plpgsql ...

CREATE OR REPLACE FUNCTION f_date_diff(_start_id int, _end_id int)
  RETURNS int LANGUAGE plpgsql AS
$func$
BEGIN

RETURN (SELECT evt_start_date 
             - (SELECT evt_start_date FROM events WHERE evt_id = _start_id)
        FROM   events WHERE evt_id = _end_id);
END
$func$;

Stessa chiamata.