如何在PL / pgSQL中编写此函数

时间:2012-07-19 23:36:54

标签: postgresql stored-procedures plpgsql window-functions

我有一个包含以下架构的表:

CREATE TABLE foo (
     the_date date,
     user_id  int,
     pop      REAL,
     hip      REAL,
     lop      REAL,
     cop      REAL
 );

我想编写一个引用前一行的函数foofunc(),并根据以下逻辑返回一个值:

function foofunc() returns numeric as $body$
begin
-- # calculate  (current_row.hip - current_row.lop) as val1 for current row
-- # calculate  abs(current_row.hip - previous_row.cop) as val2
-- # calculate  abs(current_row.lop - previous_row.cop) as val3 
-- RETURN max(val1, val2, val3)
end;
$body$ language plpgsql

我希望能够像这样调用函数foofunc()

SELECT foofunc()
from foo 
where the_date between date1 and date2 
and user_id=some_id;

如何实施foofunc()

1 个答案:

答案 0 :(得分:2)

假设“previous”由the_date ..

定义

实际上你并不需要一个plpgsql函数。带窗口函数的普通查询可以完成工作,而且速度也快得多:

WITH x AS (
    SELECT *
          ,lag(cop,1,0::real) OVER (ORDER BY the_date) AS p_cop
    FROM   foo
    WHERE  the_date <= <date2> -- don't exclude earlier rows yet
    AND    user_id = <some_id>
    )
SELECT GREATEST (
       hip - lop
      ,@(hip - p_cop)
      ,@(lop - p_cop)
       )
FROM   x
WHERE  the_date >= <date1>
ORDER  BY the_date;

如果您确实需要一个功能:

CREATE OR REPLACE FUNCTION foofunc(_user_id int, _date date)
 RETURNS real AS
$BODY$
BEGIN

RETURN (
    WITH x AS (
        SELECT *
              ,lag(cop,1,0::real) OVER (ORDER BY the_date) AS p_cop
        FROM   foo
        )
    SELECT GREATEST(
         hip - lop
        ,@(hip - p_cop)
        ,@(lop - p_cop)
        )
    FROM   x
    WHERE  the_date = _date
    AND    user_id  = _user_id
    );

END;
$BODY$ language plpgsql;

呼叫:

SELECT foofunc(1, '2012-07-21');
相关问题