一周中SSMS的滚动平均值

时间:2019-04-08 18:27:34

标签: sql-server ssms

领导力想知道队友在星期一和星期五与其他工作周相比的表现。以下是Teammate X在两个月内的每日表现的示例dbo。随后的每个队友都有一个不同的起点。最初,我着眼于结合各种开始日期使用UNBOUNDED PRECEDING,但是Windows函数无法配合使用。救命!

CREATE TABLE #RollingAverage
(
    [Date]     DATE PRIMARY KEY
    ,[Value]   INT
);

INSERT INTO #RollingAverage
SELECT '2019-01-02',626
UNION ALL SELECT '2019-01-03',231 UNION ALL SELECT '2019-01-04',572
UNION ALL SELECT '2019-01-07',775 UNION ALL SELECT '2019-01-09',660
UNION ALL SELECT '2019-01-10',662 UNION ALL SELECT '2019-01-11',541
UNION ALL SELECT '2019-01-14',849 UNION ALL SELECT '2019-01-15',632
UNION ALL SELECT '2019-01-16',906 UNION ALL SELECT '2019-01-18',961
UNION ALL SELECT '2019-01-21',501 UNION ALL SELECT '2019-01-24',311
UNION ALL SELECT '2019-01-25',614 UNION ALL SELECT '2019-01-28',296
UNION ALL SELECT '2019-01-29',390 UNION ALL SELECT '2019-01-31',804
UNION ALL SELECT '2019-02-01',928 UNION ALL SELECT '2019-02-05',855
UNION ALL SELECT '2019-02-06',605 UNION ALL SELECT '2019-02-08',283
UNION ALL SELECT '2019-02-12',144 UNION ALL SELECT '2019-02-14',382
UNION ALL SELECT '2019-02-15',862 UNION ALL SELECT '2019-02-18',549
UNION ALL SELECT '2019-02-19',401 UNION ALL SELECT '2019-02-20',515
UNION ALL SELECT '2019-02-21',590 UNION ALL SELECT '2019-02-22',625
UNION ALL SELECT '2019-02-25',304 UNION ALL SELECT '2019-02-26',402
UNION ALL SELECT '2019-02-27',326;

AVG(Value) over (ORDER BY [Date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)无效

1 个答案:

答案 0 :(得分:0)

您需要了解的第一件事是,您的“日常”表现不是每天。一个简单的解决方案是填补空白,以便能够有效地计算天数。

我使用了CTE来填补空白,该CTE可以即时生成日历表,但是您可以使用永久性的日历表。

WITH 
E(n) AS(
    SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
    SELECT a.n FROM E a, E b
),
cteCalendar(calDate) AS(
    SELECT TOP (61) 
        CAST( DATEADD( DD, 1-ROW_NUMBER() OVER(ORDER BY (SELECT NULL)), GETDATE()) AS date) AS calDate
    FROM E2
),
cteRollingAverages AS(        
    SELECT ra.[Date], 
        ra.value,
        AVG(Value) over (ORDER BY calDate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) RollingAverage
    FROM #RollingAverage AS ra
    RIGHT JOIN cteCalendar AS c ON ra.[Date] = c.calDate
)
SELECT *
FROM cteRollingAverages
WHERE [Date] IS NOT NULL
ORDER BY [Date];

另一种选择是使用APPLY。这不受特定日期的限制。

SELECT *
FROM #RollingAverage r
CROSS APPLY( SELECT AVG(i.[Value]) AS RollingAvg
            FROM #RollingAverage i
            WHERE i.[Date] BETWEEN DATEADD( DD, -7, r.[Date]) AND r.[Date]) av
ORDER BY [Date];