sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL-datumverschil

Foutopsporing

Wat uw functie doet, kan veel worden gedaan eenvoudiger. De werkelijke oorzaak van de syntaxisfout is hier:

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

Het lijkt erop dat je startDate probeert te casten naar timestamp , wat in het begin onzin is, omdat uw parameter startDate wordt gedeclareerd als timestamp al.

Het werkt ook niet. Ik citeer de handleiding hier :

Het zou werk als volgt:

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

Maar dat zou nog niet veel zin hebben. Je hebt het over "datums", maar definieert je parameters nog steeds als timestamp . Je zou ontsmet wat je hebt als volgt:

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 slechts één keer nodig.
  • date kolommen gedeclareerd als het juiste type date .
  • Gebruik geen hoofdletter-ID's, tenzij u precies weet wat u doet.
  • Trek de start af vanaf het einde om een ​​positief getal te krijgen of de absolute value-operator @ .
  • Sinds het aftrekken van datums (in tegenstelling tot het aftrekken van tijdstempels , wat een interval . oplevert ) levert al integer op , vereenvoudigen tot:

    SELECT (startDate - endDate) INTO diffDatePart;
    

    Of nog eenvoudiger als plpgsql-opdracht:

    diffDatePart := (startDate - endDate);
    

Eenvoudige vraag

U kunt de eenvoudige taak oplossen met een eenvoudige query - met behulp van een subquery:

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

Of je kunt CROSS JOIN de basistabel naar zichzelf (1 rij van elke instantie, dus dat is goed):

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-functie

Als je een functie voor dit doel wilt gebruiken, gebruik dan een eenvoudige sql-functie:

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

Bel:

SELECT  f_date_diff(5, 6);

PL/pgSQL-functie

Als je aandringt op 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$;

Zelfde oproep.



  1. Dynamische draaitabelkolommen mysql

  2. Slaapstand + PostgreSQL + netwerkadrestype (inet, cdir)

  3. Een update-trigger gebruiken om een ​​andere tabel bij te werken

  4. MySql-tabelgegevens in een array selecteren