在SQL中移动4行计算总和

时间:2016-01-05 22:01:02

标签: sql sql-server azure-sqldw

我有以下数据。

   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_CountPOS_QtyPOS_Sales,和POS_Cost

例如,如果我想要201548的数据,它将包含201548,201547,20156和201545。

201547的总和将包含201547,201546,201545和201544。

成功运行时,查询应返回4行。

我如何制定递归查询来执行此操作?这样做有什么比递归更容易吗?

编辑:版本为Azure Sql DW,版本号为12.0.2000。 Edit2:应该返回的四行将包含自己的列和它前三周的列的总和。

例如,如果我想要201548的数据,它将返回以下内容:

WM_Week POS_Store_Count POS_Qty  POS_Sales   POS_Cost
------  --------------- -------  --------    --------
201548  15780           274938   544433.79   371166.3

来自201548201547201546201545的四个(非同一性)列的总和。

4 个答案:

答案 0 :(得分:7)

很确定这会得到你想要的东西..我在订购数据后使用交叉申请来申请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 

答案 1 :(得分:1)

您可以将SUM()OVER Clause

结合使用

类似的东西:

SELECT WM_Week.
, SUM(POS_Store_Count) OVER (ORDER BY WM_Week ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
FROM Table

答案 2 :(得分:1)

您应该可以使用SQL窗口函数。

在查询中添加一列,如下所示:

SUM(POS_Sales) OVER(
   ORDER BY WM_Week 
   ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
) AS POS_Sales_4_Weeks

答案 3 :(得分:0)

如果我理解正确,你不想返回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演示示例(抱歉小提琴现在不支持sql server,所以语法稍微偏离):