use*_*927 6 sql-server aggregate t-sql window-functions
我有以下输入,我需要计算每个类别前 x 周数的值的总和。
如果 x 为 3,输出将如下所示:
请注意,最后一个值为 49,因为自 x=3 以来,它仅将上周的值添加到当前周。
我希望将 SQL 编写为存储过程,并且需要一些有关执行此操作的适当方法的帮助。
在@sp_BlitzErik 的帮助下,我尝试使用LAG,但无法完全到达我需要的地方。这是我的查询:
SELECT category
,year
,week
,value
,(
LAG(value, 1, 0) OVER (
ORDER BY category
,year
,week
) + LAG(value, 2, 0) OVER (
ORDER BY category
,year
,week
) + value
) AS cumulative_value
FROM valuedata
Run Code Online (Sandbox Code Playgroud)
输出还不太正确:
在 SQL Server 2014 和 2016 1 上,您可以使用WINDOW
函数(即OVER
子句)来执行您想要的操作:
SELECT
category, year, week, value,
sum(value) OVER (PARTITION BY category
ORDER BY year, week
ROWS 2 PRECEDING) AS retention_value_3_weeks
FROM
t
ORDER BY
category, year, week ;
Run Code Online (Sandbox Code Playgroud)
这是你会得到的结果:
类别 | 年 | 一周 | 价值 | 保留价值_3_周 :------- | ---: | ---: | ----: | ---------------: | 2016 | 1 | 5 | 5 | 2016 | 2 | 7 | 12 | 2016 | 3 | 8 | 20 乙 | 2016 | 3 | 6 | 6 乙 | 2016 | 4 | 15 | 21 乙 | 2016 | 5 | 25 | 46 | | 2016 | 3 | 25 | 25 | | 2016 | 4 | 2 | 27 | | 2016 | 5 | 21 | 48 | | 2016 | 6 | 26 | 49
请注意,x = 3
您的示例的 被转换为(当前行和2 preceding
那些)。
如果由于某种原因,您不能使用该OVER
子句,您仍然可以使用一些(相当复杂的)子查询来计算相同的结果:
SELECT
category, year, week, value,
(SELECT
sum(value)
FROM
(SELECT TOP 3 /* total number of rows to consider */
value
FROM
t t2
WHERE
t2.category = t.category /* partition by category */
AND t2.week <= t.week /* current and preceding rows */
ORDER BY
year DESC, week DESC /* order by criteria */
) AS q
) AS retention_value_3_weeks
FROM
t
ORDER BY
category, year, week ;
Run Code Online (Sandbox Code Playgroud)
在此处的dbfiddle 中查看所有内容
如果你想使用@x
而不是3
,你可以这样做:
DECLARE @x AS INTEGER = 3;
SELECT
category, year, week, value,
(SELECT
sum(value)
FROM
(SELECT TOP (@x) /* total number of rows to consider */
value
FROM
t t2
WHERE
t2.category = t.category /* partition by category */
AND t2.week <= t.week /* current and preceding rows */
ORDER BY
year DESC, week DESC /* order by criteria */
) AS q
) AS retention_value_3_weeks
FROM
t
ORDER BY
category, year, week ;;
Run Code Online (Sandbox Code Playgroud)
dbfiddle在这里
1)无法使用 SQL Server 2012 进行测试,因为我没有。MS SQL Server 的文档表明它应该从 2008 版开始可用。