【问题标题】:Recursive Decaying Average in Sql Server 2012Sql Server 2012 中的递归衰减平均值
【发布时间】:2015-07-05 21:45:53
【问题描述】:

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

我想出了一个产生正确结果的 CTE 查询,但它取决于连续的行号。我想知道在 SQL 2012 中是否有更好的方法来做到这一点,也许是使用 Over() 的新窗口函数,或者类似的东西?

在实时数据中,行按时间排序。我可以使用 SQL 视图和 ROW_NUMBER() 为我的 CTE 方法生成必要的 Row 字段,但如果有更有效的方法来执行此操作,我希望尽可能保持高效。

我有一个包含 2 列的示例表:Row int 和 Value Float。我有 1、2、3、4、4、4 的 6 个样本数据值。正确的结果应该是 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 中是否有更有效和/或更简单的方法来执行此操作,或者这是唯一的方法?谢谢。

【问题讨论】:

  • 你的递归 CTE 结果绝对正确吗?因为第一行相对于所有其他行衰减得更少?如果不从我的答案中删除iif
  • 正确。但第一行并不特别。 1 个元素的结果就是该元素的值。添加第二个元素,之前的结果占 50% 权重,新值占 50%。添加第三个值,然后(前两个元素的)先前结果为 50%,第三个元素为 50%。依此类推,直到系列结束。最后一个元素的权重始终为 50%,另外 50% 是添加最后一个元素之前的先前结果。
  • 嗯,它的特别之处在于,当您查看它最终对最终总数的贡献时,它是唯一的行,其数量没有其继任者的一半。因为它直到第二行开始发挥作用才减半,并且第二行立即减半。

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


【解决方案1】:

一种可能的选择是

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) 上的索引来避免排序。

【讨论】:

  • 看起来这确实为示例系列提供了相同的结果,并且与其他一些示例系列也匹配我的。而且它看起来肯定会更有效率。唯一的问题是我不知道它是如何工作或为什么工作的:) 猜猜我有一些阅读要做。如果权重不同怎么办?假设最后一个元素的权重为 60%,而先前的结果为 40%。这种方法还能用吗?
  • 是的,看起来上面的最新版本的小提琴做的一切都是正确的,即使权重不同。不得不说我永远不会自己想出这个,所以我很高兴我在这里问。如果 Management Studio 的“查询成本”估算准确,那么您的解决方案也比我的解决方案快两倍。感谢您的帮助。
猜你喜欢
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2015-05-22
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多