我有一个PostgreSQL函数来计算日期差:
CREATE OR REPLACE FUNCTION testDateDiff () RETURNS int AS $BODY$ DECLARE startDate TIMESTAMP; DECLARE endDate TIMESTAMP; DECLARE diffDatePart int ; BEGIN Select evt_start_date From events Where evt_id = 5 INTO startDate ; Select evt_start_date From events Where evt_id = 6 INTO endDate ; SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart; RETURN diffDatePart; END; $BODY$ LANGUAGE plpgsql COST 100
如果直接减去日期,则会计算出差额。但是在我的情况下,日期在变量asstartDate和中存在endDate,这导致了问题。
startDate
endDate
如何减去变量中包含的日期?
你的函数是做可以做 很多 简单。语法错误的实际原因在这里:
SELECT EXTRACT(day FROM TIMESTAMP startDate - endDate) INTO diffDatePart;
看来您正在尝试转换startDate为timestamp,这是毫无意义的,因为您的参数startDate已声明为timestamp已经。
timestamp
这也行不通。我在这里引用手册:
为避免语法歧义,“字符串”类型的语法只能用于指定简单文字常量的类型。
它 会 像这样工作:
SELECT EXTRACT(day FROM startDate - endDate)::int INTO diffDatePart;
但这仍然没有多大意义。您在谈论“日期”,但仍将参数定义为timestamp。您 可以这样 消毒:
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
date
@
interval
integer
SELECT (startDate - endDate) INTO diffDatePart;
甚至比plpgsql分配更简单:
diffDatePart := (startDate - endDate);
您可以通过简单的查询来解决简单的任务-使用子查询:
SELECT (SELECT evt_start_date FROM events WHERE evt_id = 6) - evt_start_date AS date_diff FROM events WHERE evt_id = 5;
或者,您也可以CROSS JOIN将基表设置为自身(每个实例1行,这样就可以了):
CROSS JOIN
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函数:
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$;
称呼:
SELECT f_date_diff(5, 6);
如果您坚持使用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$;
相同的电话。