sql >> Base de Datos >  >> RDS >> PostgreSQL

Diferencia de fecha de PostgreSQL

Depuración

Lo que está haciendo su función se podría hacer mucho más simple La causa real del error de sintaxis está aquí:

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

Parece que estás intentando lanzar startDate a timestamp , lo cual es una tontería para empezar, porque su parámetro startDate se declara como timestamp ya.

Tampoco funciona. Cito el manual aquí :

sería funciona así:

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

Pero eso todavía no tendría mucho sentido. Está hablando de "fechas", pero aún define sus parámetros como timestamp . podrías desinfecta lo que tienes así:

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 solo se necesita una vez.
  • date columnas declaradas como tipo propio date .
  • No utilice identificadores de mayúsculas y minúsculas, a menos que sepa exactamente lo que está haciendo.
  • Restar el inicio desde el final para obtener un número positivo o aplicar el operador de valor absoluto @ .
  • Desde restar fechas (en lugar de restar marcas de tiempo , que produce un interval ) ya produce integer , simplificar a:

    SELECT (startDate - endDate) INTO diffDatePart;
    

    O incluso más simple como asignación plpgsql:

    diffDatePart := (startDate - endDate);
    

Consulta sencilla

Puede resolver la tarea simple con una consulta simple, usando una subconsulta:

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

O podrías CROSS JOIN la tabla base a sí misma (1 fila de cada instancia, así que está bien):

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;

Función SQL

Si insiste en una función para este propósito, use una función sql simple:

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$;

Llamar:

SELECT  f_date_diff(5, 6);

Función PL/pgSQL

Si insiste en 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$;

Misma llamada.