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

Différence de date PostgreSQL

Débogage

Ce que fait votre fonction pourrait être fait beaucoup plus simple. La cause réelle de l'erreur de syntaxe est ici :

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

Il semble que vous essayez de caster startDate à timestamp , ce qui est un non-sens pour commencer, car votre paramètre startDate est déclaré comme timestamp déjà.

Cela ne fonctionne pas non plus. Je cite le manuel ici :

Cela serait fonctionne comme ceci :

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

Mais cela n'aurait toujours pas beaucoup de sens. Vous parlez de "dates", mais définissez toujours vos paramètres comme timestamp . Vous pourriez désinfectez ce que vous avez comme ceci :

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 nécessaire une seule fois.
  • date colonnes déclarées avec le type approprié date .
  • N'utilisez pas d'identifiants à casse mixte, sauf si vous savez exactement ce que vous faites.
  • Soustrayez le début de la fin pour obtenir un nombre positif ou appliquer l'opérateur de valeur absolue @ .
  • Depuis la soustraction des dates (au lieu de soustraire les horodatages , ce qui donne un interval ) donne déjà integer , simplifier :

    SELECT (startDate - endDate) INTO diffDatePart;
    

    Ou encore plus simple comme affectation plpgsql :

    diffDatePart := (startDate - endDate);
    

Requête simple

Vous pouvez résoudre la tâche simple avec une requête simple - en utilisant une sous-requête :

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

Ou vous pouvez CROSS JOIN la table de base à elle-même (1 ligne de chaque instance, donc ça va):

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;

Fonction SQL

Si vous insistez sur une fonction dans ce but, utilisez une simple fonction 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$;

Appel :

SELECT  f_date_diff(5, 6);

Fonction PL/pgSQL

Si vous insistez sur 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$;

Même appel.