计算 SQL 中移动 4 行的总和
Calculate Sum From Moving 4 Rows in SQL
我有以下数据。
WM_Week POS_Store_Count POS_Qty POS_Sales POS_Cost
------ --------------- ------ -------- --------
201541 3965 77722 153904.67 102593.04
201542 3952 77866 154219.66 102783.12
201543 3951 70690 139967.06 94724.60
201544 3958 70773 140131.41 95543.55
201545 3958 76623 151739.31 103441.05
201546 3956 73236 145016.54 98868.60
201547 3939 64317 127368.62 86827.95
201548 3927 60762 120309.32 82028.70
我需要编写一个 SQL 查询来获取最近四个星期的数据,并为以下列每一列汇总最近四个星期的数据:POS_Store_Count
、POS_Qty
、 POS_Sales
,以及 POS_Cost
。
例如,如果我想要 201548 的数据,它将包含 201548、201547、201546 和 201545 的数据。
201547 的总和将包含 201547、201546、201545 和 201544。
当 运行 成功时,查询应该 return 4 行。
我将如何制定递归查询来执行此操作?有没有比递归更容易做到这一点?
编辑:版本为 Azure Sql DW,版本号为 12.0.2000。
Edit2:应该 returned 的四行将具有来自其自身的列的总和,并且它是前三周。
例如,如果我想要 201548 的数字,它将 return 如下:
WM_Week POS_Store_Count POS_Qty POS_Sales POS_Cost
------ --------------- ------- -------- --------
201548 15780 274938 544433.79 371166.3
这是 201548
、201547
、201546
和 201545
.
中四列(非同一列)的总和
如果我没理解错的话,您不想 return 4 行,而是每组 4 列求和?如果是这样,这里有一个选项:
select max(WM_Week) as WM_Week,
sum(POS_Store_Count),
sum(POS_Qty),
sum(POS_Sales),
sum(POS_Cost)
from (select top 4 *
from yourtable
where wm_week <= 201548
order by wm_week desc) t
这使用带有 top
的子查询来根据 where
条件和 order by
子句获取要聚合的 4 行。
这里是一个精简的 fiddle 演示示例(抱歉 fiddle 目前不支持 sql 服务器,因此语法略有偏差):
很确定这会得到你想要的。我在订购数据后使用交叉应用来应用 SUMS
Create Table #WeeklyData (WM_Week Int, POS_Store_Count Int, POS_Qty Int, POS_Sales Money, POS_Cost Money)
Insert #WeeklyData Values
(201541,3965,77722,153904.67,102593.04),
(201542,3952,77866,154219.66,102783.12),
(201543,3951,70690,139967.06,94724.6),
(201544,3958,70773,140131.41,95543.55),
(201545,3958,76623,151739.31,103441.05),
(201546,3956,73236,145016.54,98868.6),
(201547,3939,64317,127368.62,86827.95),
(201548,3927,60762,120309.32,82028.7)
DECLARE @StartWeek INT = 201548;
WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY [WM_Week] DESC) rn
FROM #WeeklyData
WHERE WM_Week BETWEEN @StartWeek - 9 AND @StartWeek
)
SELECT *
FROM cte c1
CROSS APPLY (SELECT SUM(POS_Store_Count) POS_Store_Count_SUM,
SUM(POS_Qty) POS_Qty_SUM,
SUM(POS_Sales) POS_Sales_SUM,
SUM(POS_Cost) POS_Cost_SUM
FROM cte c2
WHERE c2.rn BETWEEN c1.rn AND (c1.rn + 3)
) ca
WHERE c1.rn <= 4
您可以将 SUM()
与 OVER Clause
结合使用
类似于:
SELECT WM_Week.
, SUM(POS_Store_Count) OVER (ORDER BY WM_Week ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM Table
您应该可以为此使用 SQL window 函数。
向您的查询添加一列,如下所示:
SUM(POS_Sales) OVER(
ORDER BY WM_Week
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
) AS POS_Sales_4_Weeks
我有以下数据。
WM_Week POS_Store_Count POS_Qty POS_Sales POS_Cost
------ --------------- ------ -------- --------
201541 3965 77722 153904.67 102593.04
201542 3952 77866 154219.66 102783.12
201543 3951 70690 139967.06 94724.60
201544 3958 70773 140131.41 95543.55
201545 3958 76623 151739.31 103441.05
201546 3956 73236 145016.54 98868.60
201547 3939 64317 127368.62 86827.95
201548 3927 60762 120309.32 82028.70
我需要编写一个 SQL 查询来获取最近四个星期的数据,并为以下列每一列汇总最近四个星期的数据:POS_Store_Count
、POS_Qty
、 POS_Sales
,以及 POS_Cost
。
例如,如果我想要 201548 的数据,它将包含 201548、201547、201546 和 201545 的数据。
201547 的总和将包含 201547、201546、201545 和 201544。
当 运行 成功时,查询应该 return 4 行。
我将如何制定递归查询来执行此操作?有没有比递归更容易做到这一点?
编辑:版本为 Azure Sql DW,版本号为 12.0.2000。 Edit2:应该 returned 的四行将具有来自其自身的列的总和,并且它是前三周。
例如,如果我想要 201548 的数字,它将 return 如下:
WM_Week POS_Store_Count POS_Qty POS_Sales POS_Cost
------ --------------- ------- -------- --------
201548 15780 274938 544433.79 371166.3
这是 201548
、201547
、201546
和 201545
.
如果我没理解错的话,您不想 return 4 行,而是每组 4 列求和?如果是这样,这里有一个选项:
select max(WM_Week) as WM_Week,
sum(POS_Store_Count),
sum(POS_Qty),
sum(POS_Sales),
sum(POS_Cost)
from (select top 4 *
from yourtable
where wm_week <= 201548
order by wm_week desc) t
这使用带有 top
的子查询来根据 where
条件和 order by
子句获取要聚合的 4 行。
这里是一个精简的 fiddle 演示示例(抱歉 fiddle 目前不支持 sql 服务器,因此语法略有偏差):
很确定这会得到你想要的。我在订购数据后使用交叉应用来应用 SUMS
Create Table #WeeklyData (WM_Week Int, POS_Store_Count Int, POS_Qty Int, POS_Sales Money, POS_Cost Money)
Insert #WeeklyData Values
(201541,3965,77722,153904.67,102593.04),
(201542,3952,77866,154219.66,102783.12),
(201543,3951,70690,139967.06,94724.6),
(201544,3958,70773,140131.41,95543.55),
(201545,3958,76623,151739.31,103441.05),
(201546,3956,73236,145016.54,98868.6),
(201547,3939,64317,127368.62,86827.95),
(201548,3927,60762,120309.32,82028.7)
DECLARE @StartWeek INT = 201548;
WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY [WM_Week] DESC) rn
FROM #WeeklyData
WHERE WM_Week BETWEEN @StartWeek - 9 AND @StartWeek
)
SELECT *
FROM cte c1
CROSS APPLY (SELECT SUM(POS_Store_Count) POS_Store_Count_SUM,
SUM(POS_Qty) POS_Qty_SUM,
SUM(POS_Sales) POS_Sales_SUM,
SUM(POS_Cost) POS_Cost_SUM
FROM cte c2
WHERE c2.rn BETWEEN c1.rn AND (c1.rn + 3)
) ca
WHERE c1.rn <= 4
您可以将 SUM()
与 OVER Clause
类似于:
SELECT WM_Week.
, SUM(POS_Store_Count) OVER (ORDER BY WM_Week ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM Table
您应该可以为此使用 SQL window 函数。
向您的查询添加一列,如下所示:
SUM(POS_Sales) OVER(
ORDER BY WM_Week
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
) AS POS_Sales_4_Weeks