每周的SSMS滚动平均值

问题描述 投票:1回答:1

领导层希望了解周一和周五队友的表现与其他工作周相比。以下是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)没有工作

sql-server ssms
1个回答
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];
© www.soinside.com 2019 - 2024. All rights reserved.