PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Diferença de data do PostgreSQL

Depurar


O que sua função está fazendo pode ser feito muito mais simples. A causa real do erro de sintaxe está aqui:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;

Parece que você está tentando converter startDate para timestamp , o que é um absurdo para começar, porque seu parâmetro startDate é declarado como timestamp já.

Também não funciona. Cito o manual aqui :

Ele seria trabalhar assim:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;

Mas isso ainda não faria muito sentido. Você está falando sobre "datas", mas ainda define seus parâmetros como timestamp . Você poderia higienize o que você tem assim:
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 necessário apenas uma vez.
  • date colunas declaradas como tipo próprio date .
  • Não use identificadores de maiúsculas e minúsculas, a menos que você saiba exatamente o que está fazendo.
  • Subtraia o início do fim para obter um número positivo ou aplique o operador de valor absoluto @ .

  • Desde a subtração de datas (em vez de subtrair timestamps , que produz um interval ) já produz integer , simplifique para:
    SELECT (startDate - endDate) INTO diffDatePart;
    

    Ou ainda mais simples como atribuição plpgsql:
    diffDatePart := (startDate - endDate);
    

Consulta simples


Você pode resolver a tarefa simples com uma consulta simples - usando uma subconsulta:
SELECT (SELECT evt_start_date
        FROM   events
        WHERE  evt_id = 6) 
      - evt_start_date AS date_diff
FROM   events
WHERE  evt_id = 5;

Ou você pode CROSS JOIN a tabela base para si mesma (1 linha de cada instância, então tudo bem):
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;

Função SQL


Se você insistir em uma função para esse fim, use uma função sql simples:
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$;

Ligar:
SELECT  f_date_diff(5, 6);

Função PL/pgSQL


Se você insistir em 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$;

Mesma chamada.