SQL Server中如何将不足4天的滚动平均值设为NULL?
解决SQL Server中滚动平均前序数据不足时显示NULL的问题
嘿,我来帮你搞定这个需求!你的原SQL语句确实在计算滚动平均,但默认情况下,当前面不足4行时,它会直接用现有数据计算平均——比如第一行只会取当天的收盘价,第二行取两天的平均,这显然不是你想要的效果。
要实现「当前行前序天数不足4天时,MA10显示NULL」的目标,我们可以用两种简洁的方式调整:
方法一:窗口内统计行数判断(无需额外CTE)
这种方式直接在SELECT语句里通过COUNT()窗口函数,判断当前窗口内的行数是否满足要求:
SELECT Date, [Close], CASE -- 窗口包含当前行+前4行,总共需要5行才意味着有4天的前序数据 WHEN COUNT(*) OVER (ORDER BY Date ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) < 5 THEN NULL ELSE AVG([Close]) OVER (ORDER BY Date ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) END AS MA10 FROM dbo.APPL;
逻辑很清晰:如果窗口内的行数少于5,说明前面的天数不够4天,返回NULL;否则正常计算这5行的平均。
方法二:用行号判断(逻辑更直观)
如果你觉得行数统计的逻辑有点绕,可以先给每行编一个递增的行号,再通过行号判断是否满足条件:
WITH RankedData AS ( SELECT Date, [Close], ROW_NUMBER() OVER (ORDER BY Date ASC) AS RowNum FROM dbo.APPL ) SELECT Date, [Close], CASE -- 前4行(行号1-4)都凑不够4天的前序数据,返回NULL WHEN RowNum < 5 THEN NULL ELSE AVG([Close]) OVER (ORDER BY Date ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) END AS MA10 FROM RankedData;
这种方式的逻辑更直白:行号小于5的行,前面没有足够的历史数据,所以MA10设为NULL;从第5行开始,就可以正常计算滚动平均了。
另外小提醒:你语句里的MA10命名有点小疑问——毕竟当前逻辑是计算5天的滚动平均(当前行+前4行),如果是想做真正的10天平均,只需要把4 PRECEDING改成9 PRECEDING,同时把判断条件里的5改成10就行~
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

