PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak obliczyć wykładniczą średnią kroczącą na postgresie?

Możesz zdefiniować własną funkcję agregującą, a następnie użyć jej ze specyfikacją okna, aby uzyskać agregowane dane wyjściowe na każdym etapie, a nie pojedynczą wartość.

Tak więc agregat to fragment stanu i funkcja transformacji do modyfikacji tego stanu dla każdego wiersza i opcjonalnie funkcja finalizująca do konwersji stanu na wartość wyjściową. W tak prostym przypadku wystarczy funkcja transformacji.

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 daje mi:

[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

Te liczby wydają się pasować do arkusza kalkulacyjnego dodanego do pytania.

Możesz także zdefiniować funkcję, która przekazuje alfa jako parametr z instrukcji:

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

Ponadto ta funkcja jest tak prosta, że ​​w ogóle nie musi być w plpgsql, ale może być tylko funkcją sql, chociaż nie możesz odwoływać się do parametrów po nazwie w jednym z nich:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyczerpano dozwolony rozmiar pamięci 8589934592 bajtów

  2. Kompilowanie zapisywalnego rozszerzenia mongo_fdw w formacie binarnym instalacji PostgreSQL.

  3. Więcej SQL, mniej kodu, z PostgreSQL

  4. W jaki sposób pgBouncer pomaga przyspieszyć działanie Django?

  5. Bardzo powolne uruchamianie aplikacji Spring Boot