我们正在尝试计算滚动平均值,并尝试转换许多SO答案以解决该问题。至此,我们仍然没有成功。
我们尝试过的是:
这是我们考虑过的一些SO答案。
我们的最新尝试是修改此处找到的解决方案之一(#4)。https://www.red-gate.com/simple-talk/sql/t-sql-programming/calculating-values-within-a-rolling-window-in-transact-sql/
范例:
这是SQL Fiddle中的示例:http ://sqlfiddle.com/#!6/4570a/17
摆弄小提琴,我们仍在尝试使SUM正常工作,但最终我们试图获得平均值。
最终目标
使用Fiddle示例,我们需要找到Value1和CompareValue1之间的差异并将其表示为Diff1。当一行没有可用的Value1时,我们需要通过取最后两个Diff1值的平均值进行估算,然后将其添加到该行的ComparisonValue1中。
使用正确的查询,结果将如下所示:
GroupID Number ComparisonValue1 Diff1 Value1
5 10 54.78 2.41 57.19
5 11 55.91 2.62 58.53
5 12 55.93 2.78 58.71
5 13 56.54 2.7 59.24
5 14 56.14 2.74 58.88
5 15 55.57 2.72 58.29
5 16 55.26 2.73 57.99
问题:当有可能将其平均计入以下各行的平均值时,是否可以计算该平均值?
更新:
这个想法归功于这个答案:@JesúsLópez的https://stackoverflow.com/a/35152131/6305294
我已在代码中包含注释以对其进行解释。
更新
现在,查询结果与您的样本输出完全匹配。
;WITH cte AS
(
-- This is similar to your ItemWithComparison view
SELECT i.Number, i.Value1, i2.Value1 AS ComparisonValue1,
-- Calculated Differences; NULL will be returned when i.Value1 is NULL
CONVERT( DECIMAL( 10, 3 ), i.Value1 - i2.Value1 ) AS Diff
FROM Item AS i
LEFT JOIN [Group] AS G ON g.ID = i.GroupID
LEFT JOIN Item AS i2 ON i2.GroupID = g.ComparisonGroupID AND i2.Number = i.Number
WHERE NOT i2.Id IS NULL
),
cte2 AS(
/*
Start with the first number
Note if you do not have at least 2 consecutive numbers (in cte) with non-NULL Diff value and therefore Diff1Ago or Diff2Ago are NULL then everything else will not work;
You may need to add additional logic to handle these cases */
SELECT TOP 1 -- start with the 1st number (see ORDER BY)
a.Number, a.Value1, a.ComparisonValue1, a.Diff, b.Diff AS Diff1Ago
FROM cte AS a
-- "1 number ago"
LEFT JOIN cte AS b ON a.Number - 1 = b.Number
WHERE NOT a.Value1 IS NULL
ORDER BY a.Number
UNION ALL
SELECT b.Number, b.Value1, b.ComparisonValue1,
( CASE
WHEN NOT b.Value1 IS NULL THEN b.Diff
ELSE CONVERT( DECIMAL( 10, 3 ), ( a.Diff + a.Diff1Ago ) / 2.0 )
END ) AS Diff,
a.Diff AS Diff1Ago
FROM cte2 AS a
INNER JOIN cte AS b ON a.Number + 1 = b.Number
)
SELECT *, ( CASE WHEN Value1 IS NULL THEN ComparisonValue1 + Diff ELSE Value1 END ) AS NewValue1
FROM cte2 OPTION( MAXRECURSION 0 );
局限性:此解决方案仅在需要考虑少量先前值时才有效。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句