sql – 如何计算Postgres上的指数移动平均线?

前端之家收集整理的这篇文章主要介绍了sql – 如何计算Postgres上的指数移动平均线?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在postgres上实现指数移动平均线(EMA),但是当我检查文档并考虑它时,我越是感到困惑.

EMA(x)的公式为:

EMA(x1) = x1
EMA(xn) = α * xn + (1 - α) * EMA(xn-1)

对于聚合器来说似乎是完美的,保持最后计算的元素的结果正是这里必须完成的.然而,聚合器产生一个单个结果(作为缩减或折叠),这里我们需要一个结果列表(一列)(如map).我一直在检查程序和功能的工作原理,但是AFAIK他们生产一个单一的输出,而不是列.我已经看到了很多程序和功能,但是我不能真正弄清楚它与关系代数的相互作用,特别是当这样做时,EMA.

到目前为止,我没有运气搜索互联网.但是EMA的定义非常简单,希望将这个定义转化为postgres中有用的东西,而且简单高效,因为在我的上下文中移动到Nosql会变得过大.

谢谢.

PD:在这里你可以看到一个例子:
https://docs.google.com/spreadsheet/ccc?key=0AvfclSzBscS6dDJCNWlrT3NYdDJxbkh3cGJ2S2V0cVE

解决方法

您可以定义自己的聚合函数,然后使用窗口规范来获取每个阶段的聚合输出,而不是单个值.

所以一个聚合是一个状态,一个变换函数修改每个行的状态,以及可选的一个完成函数来将状态转换为一个输出值.对于这样一个简单的例子,只需要一个变换函数即可.

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

这给我:

steve@steve@[local] =# select x,ema(x,0.1) over(w),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,0.5 /* alpha */) over (order by n asc) from data

另外,这个函数实际上是这么简单的,它根本不需要在plpgsql中,但是可以只是一个sql函数,尽管你不能通过名称引用参数:

create or replace function ema_func(state numeric,alpha numeric)
  returns numeric
  language sql as $$
select case
       when $1 is null then $2
       else $3 * $2 + (1-$3) * $1
       end
$$;
原文链接:https://www.f2er.com/mssql/82317.html

猜你在找的MsSQL相关文章