sql >> データベース >  >> RDS >> PostgreSQL

postgresで指数移動平均を計算する方法は?

    独自の集計関数を定義し、それをウィンドウ仕様で使用して、単一の値ではなく、各段階で集計出力を取得できます。

    したがって、集計は状態の一部であり、行ごとにその状態を変更するための変換関数であり、オプションで、状態を出力値に変換するためのファイナライズ関数です。このような単純なケースでは、変換関数だけで十分です。

    create function ema_func(numeric, numeric) returns numeric
      language plpgsql as $$
    declare
      alpha numeric := 0.5;
    begin
      -- uncomment the following line to see what the parameters mean
      -- raise info 'ema_func: % %', $1, $2;
      return case
                  when $1 is null then $2
                  else alpha * $2 + (1 - alpha) * $1
             end;
    end
    $$;
    create aggregate ema(basetype = numeric, sfunc = ema_func, stype = numeric);
    

    それは私に:

    [email protected]@[local] =# select x, ema(x, 0.1) over(w), ema(x, 0.2) over(w) from data window w as (order by n asc) limit 5;
         x     |      ema      |      ema      
    -----------+---------------+---------------
     44.988564 |     44.988564 |     44.988564
       39.5634 |    44.4460476 |    43.9035312
     38.605724 |   43.86201524 |   42.84396976
     38.209646 |  43.296778316 |  41.917105008
     44.541264 | 43.4212268844 | 42.4419368064
    

    これらの数値は、質問に追加したスプレッドシートと一致しているようです。

    また、ステートメントからパラメータとしてアルファを渡す関数を定義できます:

    create or replace function ema_func(state numeric, inval numeric, alpha numeric)
      returns numeric
      language plpgsql as $$
    begin
      return case
             when state is null then inval
             else alpha * inval + (1-alpha) * state
             end;
    end
    $$;
    
    create aggregate ema(numeric, numeric) (sfunc = ema_func, stype = numeric);
    
    select x, ema(x, 0.5 /* alpha */) over (order by n asc) from data
    

    また、この関数は実際には非常に単純なので、plpgsqlに含める必要はありませんが、次のいずれかでパラメータを名前で参照することはできませんが、単なるsql関数にすることができます。

    create or replace function ema_func(state numeric, inval numeric, alpha numeric)
      returns numeric
      language sql as $$
    select case
           when $1 is null then $2
           else $3 * $2 + (1-$3) * $1
           end
    $$;
    


    1. .NET / SQLのテーブル名をパラメータ化しますか?

    2. ダウンタイムなしでPostgreSQL10をPostgreSQL11にアップグレードする方法

    3. 読み取り専用のMySQLユーザーを作成するにはどうすればよいですか?

    4. 列の変更:nullからnot null