0

我有一个具有以下架构的表:

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()

4

1 回答 1

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');
于 2012-07-20T01:26:03.910 回答