Sql Server 2012中的递归衰减平均值

时间:2015-07-05 21:45:54

标签: sql-server recursion sql-server-2012 common-table-expression

我需要计算一组值的衰减平均值(累积移动?)。该系列中的最后一个值是50%权重,所有先前系列的平均衰减为另外50%权重,递归。

我提出了一个产生正确结果的CTE查询,但它取决于顺序行号。我想知道在SQL 2012中是否有更好的方法可以执行此操作,可能使用Over()的新窗口函数,或类似的东西?

在实时数据中,行按时间排序。我可以使用SQL视图和ROW_NUMBER()为我的CTE方法生成必要的Row字段,但是如果有更有效的方法来做到这一点,我想尽可能保持高效。

我有一个包含2列的示例表:Row int和Value Float。我有6个样本数据值1,2,3,4,4,4。正确的结果应该是3.78125。

我的解决方案是:

;WITH items AS (
  SELECT TOP 1 
    Row, Value, Value AS Decayed
    FROM Sample Order By Row
  UNION ALL
  SELECT v.Row, v.Value, Decayed * .5 + v.Value *.5 AS Decayed
  FROM Sample v
  INNER JOIN items itms ON itms.Row = v.Row-1
  )
SELECT top 1 Decayed FROM items order by Row desc

使用测试数据正确生成3.78125。我的问题是:在SQL 2012中有更高效和/或更简单的方法吗,或者这是唯一的方法吗?感谢。

1 个答案:

答案 0 :(得分:3)

一种可能的替代方案是

WITH T AS
(
SELECT      
 Value * POWER(5E-1, ROW_NUMBER() 
                     OVER (ORDER BY Row DESC)
               /* first row decays less so special cased */
              -IIF(LEAD(Value) OVER (ORDER BY Row DESC) IS NULL,1,0))
       as x
FROM Sample
)
SELECT SUM(x)
FROM T

SQL Fiddle

或者使用60%/ 40%的更新问题

WITH T AS
(
SELECT   IIF(LEAD(Value) OVER (ORDER BY Row DESC) IS NULL,  1,0.6)
         * Value 
         * POWER(4E-1, ROW_NUMBER() OVER (ORDER BY Row DESC) -1)
       as x
FROM Sample
)
SELECT SUM(x)
FROM T

SQL Fiddle

以上两者都会对数据执行单次传递,并且可能会使用Row INCLUDE(Value)上的索引来避免排序。