TSQL moving AVG()在前面的范围为null时返回null。。。超过1列

TSQL moving AVG()在前面的范围为null时返回null。。。超过1列,sql,tsql,count,average,window-functions,Sql,Tsql,Count,Average,Window Functions,嗨,我的表中有几列,如果前面的行为空,我希望移动平均值返回空 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,V1,V2) VALUES ('01-02-2020',3,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,V1,V2) VALUES ('01-02-2020',3,NULL)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-03-2020',1,NULL)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-04-2020',9,NULL)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-05-2020',12,NULL)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-06-2020',3,4)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-07-2020',4,8)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-08-2020',15,12)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-09-2020',5,17)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-10-2020',10,9)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-11-2020',14,2)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-12-2020',12,5)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-13-2020',8,6)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-14-2020',7,29)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-15-2020',4,6)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-16-2020',2,8)
INSERT INTO dbo.TESTMOVINGAVG (VDATE,V1,V2) VALUES ('01-17-2020',1,10)

SELECT VDATE,
       V1,
       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
但是我应该在v2movavg中有空值,直到vdate=01-10-2020。当没有空值时,rownumber>4适用于移动平均值为5的情况。但是,当我的一列中有n个空值时,我该怎么做呢


John

我想你想要的逻辑是
count()


我认为您需要的逻辑是
count()


我知道您希望前面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()
忽略
null
值这一事实。

我知道您希望前面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()
忽略
null
值这一事实。

使用
count(V2)OVER(…)
检查窗口中非空值的数量?使用
count(V2)OVER(…)
检查窗口中非空值的数量?