sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL datumskillnad

Felsök

Vad din funktion gör kan göras mycket enklare. Den faktiska orsaken till syntaxfelet finns här:

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

Det verkar som att du försöker casta startDate till timestamp , vilket är nonsens till att börja med, eftersom din parameter startDate deklareras som timestamp redan.

Det fungerar inte heller. Jag citerar handboken här :

Det skulle fungerar så här:

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

Men det skulle fortfarande inte vara särskilt vettigt. Du talar om "datum", men definierar fortfarande dina parametrar som timestamp . Du kunde rensa det du har så här:

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 behövs bara en gång.
  • date kolumner som deklarerats som korrekt typ date .
  • Använd inte identifierare med blandade skiftlägen om du inte vet exakt vad du gör.
  • Subtrahera start från slutet för att få ett positivt tal eller använd absolutvärdesoperatorn @ .
  • Sedan du har subtraherat datum (i motsats till att subtrahera tidsstämplar , vilket ger ett interval ) ger redan integer , förenkla till:

    SELECT (startDate - endDate) INTO diffDatePart;
    

    Eller ännu enklare som plpgsql-tilldelning:

    diffDatePart := (startDate - endDate);
    

Enkel fråga

Du kan lösa den enkla uppgiften med en enkel fråga - med hjälp av en underfråga:

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

Eller så kan du CROSS JOIN bastabellen för sig själv (1 rad från varje instans, så det är 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;

SQL-funktion

Om du insisterar på en funktion för ändamålet, använd en enkel sql-funktion:

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

Ring:

SELECT  f_date_diff(5, 6);

PL/pgSQL-funktion

Om du insisterar på 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$;

Samma samtal.



  1. MYSQL - Sammanfoga två tabeller

  2. Ny MySQL-drivrutin orsakar java.sql.SQLNonTransientConnectionException:CLIENT_PLUGIN_AUTH krävs

  3. Tabellalias fungerar inte i rå Oracle SQL-frågor i Django

  4. ClusterControl - Advanced Backup Management - mariabackup del III