我有一张包含以下数据的表格:
Month|Order|OrdersAcc
APR |4 |4
MAY |3 |7
我需要的是从五月而不是四月开始累积,这意味着结果应该是:
Month|Order|OrdersAcc
APR |4 | NULL
MAY |3 |4
JUN |2 |7
JUL |4 |9
请协助查询以实现此目的。
让我简化一下。这是执行累积的查询:
SELECT SUM(t2.OrdersAcc) AS OrdersAcc, t1.MONTH_sort2, t1.ActMonth
FROM dbo.tbl_ME_OrderCompletions AS t1 INNER JOIN
(SELECT SUM(Orders) AS OrdersAcc, Region, MONTH_sort2
FROM dbo.tbl_ME_OrderCompletions
GROUP BY Region, MONTH_sort2, ActMonth) AS t2 ON t1.Region = t2.Region AND t1.MONTH_sort2 >= t2.MONTH_sort2
GROUP BY t1.Region, t1.MONTH_sort2, ActMonth
我正在使用month_sort2列,因为它有从1到12的增量整数,1表示4月,2表示5月,依此类推。 第一个月(四月)的数据需要在5月份显示,然后从五月开始需要累积。我希望这是有帮助的。
答案 0 :(得分:0)
如果您使用的是SQL Server 2012或更高版本,我建议您查看窗口函数 - 尤其是LEAD& LAG。
还有其他方法可以做到这一点,但它展示了窗口函数的强大功能以及如何将它们链接在一起。
CREATE TABLE dbo.tbl_ME_OrderCompletions
(
Month_Sort2 INT
,Orders INT
,Region NVARCHAR(20)
)
INSERT INTO dbo.tbl_ME_OrderCompletions
VALUES (1,4,'Placeholder')
,(2,3,'Placeholder')
,(3,2,'Placeholder')
,(4,4,'Placeholder')
,(5,3,'Placeholder')
,(6,1,'Placeholder')
,(7,2,'Placeholder')
,(8,4,'Placeholder')
,(9,3,'Placeholder')
,(10,7,'Placeholder')
,(11,3,'Placeholder')
,(12,9,'Placeholder')
SELECT UPPER(CONVERT(NVARCHAR(3),DATENAME(mm,DATEADD(mm,t.MonthID + 3,-1)))) AS Month
,t.Orders
,LAG(t.SumOrders) OVER (ORDER BY MonthID) AS OrdersAcc
FROM
(
SELECT o.Month_Sort2 AS MonthID
,o.Orders AS Orders
,SUM(o.Orders) OVER (ORDER BY o.Month_Sort2) AS SumOrders
FROM dbo.tbl_ME_OrderCompletions o
) t
答案 1 :(得分:0)
您可以尝试以下操作:
DECLARE @DataSource TABLE
(
[month_row_id] INT
,[motnh] VARCHAR(12)
,[order] INT
);
INSERT INTO @DataSource ([month_row_id], [motnh], [order])
VALUES (1, 'APR', 4)
,(2, 'MAY', 3)
,(3, 'JUN', 2)
,(4, 'JULY',4);
SELECT [motnh]
,[order]
,SUM([order]) OVER (ORDER BY [month_row_id] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - [order] AS [OrderAcc]
FROM @DataSource;
我们的想法是将值累积到当前行,但使用简单的-
操作排除当前行值。
另请注意,我添加了month_row_id
列,以便能够及时订购行,因为使用月份名称无效。
答案 2 :(得分:0)
我找到了解决方案。
SELECT SUM(t2.OrdersAcc) AS OrdersAcc, t1.MONTH_sort2, t1.ActMonth
FROM dbo.tbl_ME_OrderCompletions AS t1 INNER JOIN
(SELECT SUM(Orders) AS OrdersAcc, Region, MONTH_sort2
FROM dbo.tbl_ME_OrderCompletions
GROUP BY Region, MONTH_sort2, ActMonth) AS t2 ON t1.MONTH_sort2 > t2.MONTH_sort2
GROUP t1.MONTH_sort2, ActMonth
我所要做的就是将Month_sort2连接从等于或大于大于。谢谢你的帮助
答案 3 :(得分:0)
你需要澄清一下你的问题。但是从我收集的内容来看,你正在寻找:
; WITH t AS (
SELECT 4 AS monthNum, 'APR' AS m, 4 AS t UNION ALL
SELECT 5 AS monthNum, 'MAY' AS m, 3 AS t UNION ALL
SELECT 6 AS monthNum, 'JUN' AS m, 2 AS t UNION ALL
SELECT 7 AS monthNum, 'JUL' AS m, 4 AS t
)
SELECT s1.m,s1.t
, SUM(s1.prevT) OVER (ORDER BY s1.monthNum ROWS UNBOUNDED PRECEDING) AS totalT
FROM (
SELECT t.monthNum, t.m, t.t
, (LAG(t.t) OVER (ORDER BY t.monthNum)) AS prevT
FROM t
) s1
;
1)这仅适用于MS SQL Server 2012或更高版本。
2)你必须有办法订购你的月份。我添加了一个monthNum列来执行此操作。
=============================================== ====
对于SQL 2008和2008R2:
; WITH t AS (
SELECT 4 AS monthNum, 'APR' AS m, 4 AS t UNION ALL
SELECT 5 AS monthNum, 'MAY' AS m, 3 AS t UNION ALL
SELECT 6 AS monthNum, 'JUN' AS m, 2 AS t UNION ALL
SELECT 7 AS monthNum, 'JUL' AS m, 4 AS t
)
SELECT t3.m, t3.t, NULLIF(t3.runningTotal, t3.t) AS nulledRunningTotal
FROM (
SELECT t.monthNum, t.m, t.t
, ( SELECT SUM(t2.t) FROM t t2 WHERE t2.monthNum <= t.monthNum ) AS runningTotal
FROM t
) t3 ;
我想这可能是我第一次使用NULLIF()
。因此,如果您需要在2008年之前,可以将NULLIF(t3.runningTotal,t3.t)
更改为CASE WHEN t3.runningTotal<>t3.t THEN t3.runningTotal ELSE NULL END
。