PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Różnica dat PostgreSQL

Debugowanie

To, co robi Twoja funkcja, można zrobić dużo prostsze. Rzeczywista przyczyna błędu składni jest tutaj:

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

Wygląda na to, że próbujesz przesłać startDate do timestamp , co na początku jest nonsensem, ponieważ Twój parametr startDate jest zadeklarowany jako timestamp już.

To też nie działa. Cytuję instrukcję tutaj :

byłoby działaj tak:

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

Ale to nadal nie miałoby sensu. Mówisz o „datach”, ale nadal definiujesz swoje parametry jako timestamp . możesz zdezynfekuj to, co masz w ten sposób:

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 potrzebne tylko raz.
  • date kolumny zadeklarowane jako właściwy typ date .
  • Nie używaj identyfikatorów wielkości liter, chyba że wiesz dokładnie, co robisz.
  • Odejmij początek od koniec aby uzyskać liczbę dodatnią lub zastosować operator wartości bezwzględnej @ .
  • Od odjęcia dat (w przeciwieństwie do odejmowania sygnatur czasowych , co daje interval ) już zwraca integer , uprość do:

    SELECT (startDate - endDate) INTO diffDatePart;
    

    Lub jeszcze prostsze, jak przypisanie plpgsql:

    diffDatePart := (startDate - endDate);
    

Proste zapytanie

Możesz rozwiązać proste zadanie za pomocą prostego zapytania - używając podzapytania:

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

Możesz też CROSS JOIN podstawowa tabela do siebie (1 wiersz z każdej instancji, więc jest ok):

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;

Funkcja SQL

Jeśli nalegasz na jakąś funkcję do tego celu, użyj prostej funkcji 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$;

Zadzwoń:

SELECT  f_date_diff(5, 6);

Funkcja PL/pgSQL

Jeśli nalegasz na 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$;

To samo połączenie.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. postgresql - wyzwalacz, aktualizacja znacznika czasu przy aktualizacji pola

  2. Jak dodać klucz do wartości tablicy JSON?

  3. Czy SQLAlchemy ma funkcję agregującą bool_and?

  4. Sequelize.js:Zapytanie o brak w tablicy ($ne dla elementów w tablicy)

  5. finder_sql nie analizuje ciągu znaków za pomocą Rails