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

「前」が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 に答える