sql >> Databáze >  >> RDS >> PostgreSQL

Jak vypočítat exponenciální klouzavý průměr na postgresu?

Můžete definovat svou vlastní agregační funkci a poté ji použít se specifikací okna k získání agregovaného výstupu v každé fázi namísto jedné hodnoty.

Agregát je tedy část stavu a transformační funkce pro úpravu tohoto stavu pro každý řádek a volitelně dokončovací funkce pro převod stavu na výstupní hodnotu. Pro jednoduchý případ, jako je tento, by měla stačit pouze transformační funkce.

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

což mi dává:

[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

Zdá se, že tato čísla odpovídají tabulce, kterou jste přidali k otázce.

Můžete také definovat funkci, která předá alfa jako parametr z příkazu:

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

Tato funkce je také ve skutečnosti tak jednoduchá, že vůbec nemusí být v plpgsql, ale může to být pouze funkce SQL, i když v jednom z nich nemůžete odkazovat na parametry podle názvu:

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. Jak mohu exportovat obsah tabulky oracle do souboru?

  2. Jak číst a aktualizovat databázi SQLite pomocí ListView v Androidu?

  3. Sladění nabídky a poptávky – Řešení, část 1

  4. Jak převést typ jsonb PostgreSQL 9.4 na plovoucí