如何解决当PRECEDING范围为NULL ...多于1列时,TSQL移动AVG返回null
您好,我的表格中有几列,并且如果所需的前一行为空,则希望移动平均值返回空。
CREATE TABLE dbo.TESTMOVINGAVG
(VDATE DATE,V1 SMALLINT,V2 SMALLINT)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-01-2020',4,NULL)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-02-2020',3,V2) VALUES ('01-03-2020',1,V2) VALUES ('01-04-2020',9,V2) VALUES ('01-05-2020',12,V2) VALUES ('01-06-2020',4)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-07-2020',8)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-08-2020',15,12)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-09-2020',5,17)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-10-2020',10,9)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-11-2020',14,2)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-12-2020',5)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-13-2020',8,6)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-14-2020',7,29)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V2) VALUES ('01-15-2020',V2) VALUES ('01-16-2020',2,V2) VALUES ('01-17-2020',10)
SELECT VDATE,CASE WHEN ROW_NUMBER() OVER(ORDER BY VDATE ) > 4 AND V1 IS NOT NULL
THEN
AVG(V1) OVER (ORDER BY VDATE ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
ELSE NULL
END AS V1MOVAVG,CASE WHEN ROW_NUMBER() OVER(ORDER BY VDATE ) > 4 AND V2 IS NOT NULL
THEN
AVG(V2) OVER (ORDER BY VDATE ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
ELSE NULL
END AS V2MOVAVG
FROM TESTMOVINGAVG
我明白了
VDATE V1 V1MOVAVG V2MOVAVG
2020-01-01 4 NULL NULL
2020-01-02 3 NULL NULL
2020-01-03 1 NULL NULL
2020-01-04 9 NULL NULL
2020-01-05 12 5 NULL
2020-01-06 3 5 4
2020-01-07 4 5 6
2020-01-08 15 8 8
2020-01-09 5 7 10
2020-01-10 10 7 10
2020-01-11 14 9 9
2020-01-12 12 11 9
2020-01-13 8 9 7
2020-01-14 7 10 10
2020-01-15 4 9 9
2020-01-16 2 6 10
2020-01-17 1 4 11
但是在vdate = 01-10-2020之前,我在v2movavg中应该为null。当没有空值时,rownumber> 4的平均值为5。但是,当我的一列中有n个空值时,该怎么办?
约翰
解决方法
我认为您想要的逻辑是count()
:
(CASE WHEN COUNT(V2) OVER (ORDER BY VDATE ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) = 5
THEN AVG (V2) OVER (ORDER BY VDATE ASC ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
END) AS V2MOVAVG
,
我知道您不希望在前4行中输入任何null
值。您可以使用窗口计数进行测试:
case when count(v1) over(order by vdate rows between 4 preceding and current row) > 0
then avg(v1) over(order by vdate rows between 4 preceding and current row)
end as v1movavg
这利用了count(<expr>)
忽略null
值的事实。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。