您可能已经知道将聚合结果滚动到特定数量的先前行上。即:过去7天内我吃了多少热狗
SELECT HotDogCount,
DateKey,
SUM(HotDogCount) OVER (ORDER BY DateKey ROWS 6 PRECEDING) AS HotDogsLast7Days
FROM dbo.HotDogConsumption
结果:
+-------------+------------+------------------+
| HotDogCount | DateKey | HotDogsLast7Days |
+-------------+------------+------------------+
| 3 | 09/21/2020 | 3 |
| 2 | 9/22/2020 | 5 |
| 1 | 09/23/2020 | 6 |
| 1 | 09/24/2020 | 7 |
| 1 | 09/25/2020 | 8 |
| 4 | 09/26/2020 | 12 |
| 1 | 09/27/2020 | 13 |
| 3 | 09/28/2020 | 13 |
| 2 | 09/29/2020 | 13 |
| 1 | 09/30/2020 | 13 |
+-------------+------------+------------------+
现在,我的问题是日期之间有间隔。因此,基本上,有一天,我的肠子和循环系统都在向我尖叫:“你到底在做什么,你会杀了我们所有人!”因此,我决定休息一天,现在没有任何记录。现在,当我使用“ ROWS 6 PRECEDING”方法时,我现在可以返回8天而不是7天,因为错过了一天。
所以,问题是,你们中的任何人是否知道我可以如何使用OVER子句真正使用日期值(例如“ DATEADD(day,-7,DateKey)”之类)来确定应该有多少行?无论我是一天只吃热狗还是整天都吃了7天,总算得出了真正的7天滚动总和?
请注意,在我没有吃任何热狗的日子里,记录为0是不可行的。我知道我可以使用日期数组并对其进行左连接并执行
CASE WHEN Datekey IS NULL THEN 0 END
交易类型,但我想找出是否存在一种不同的方法,可以根据日期动态确定行前值。
答案 0 :(得分:3)
从理论上讲,窗口函数是正确的方法。但是要回顾过去的7天(不是行),我们需要一个range
框架规范-不幸的是,SQL Server不支持该框架规范。
我将推荐一个子查询或横向联接:
select hdc.*, hdc1.*
from dbo.HotDogConsumption hdc
cross apply (
select coalesce(sum(HotDogCount), 0) HotDogsLast7Days
from dbo.HotDogConsumption hdc1
where hdc1.datekey >= dateadd(day, -7, hdc.datekey)
and hdc1.datekey < hdc.datekey
) hdc1
您可能希望将子查询的where
子句中的条件调整为所需的精确框架。上面的代码是最近7天(不包括今天)的计算结果。相当于您当前尝试的内容将是:
where hdc1.datekey >= dateadd(day, -6, hdc.datekey)
and hdc1.datekey <= hdc.datekey
答案 1 :(得分:1)
我有点老,但这就是我要去的方式:
SELECT
HDC1.HotDogCount
,HDC1.DateKey
,( SELECT SUM( HDC2.HotDogCount )
FROM HotDogConsumption HDC2
WHERE HDC2.DateKey BETWEEN DATEADD( DD, -7, HDC1.DateKey )
AND HDC1.DateKey ) AS 'HotDogsLast7Days'
FROM
HotDogConsumption HDC1
;
年龄较小的人可能会使用OUTER APPLY之类的东西。