我已经尝试过并且未能适应几种运行总和方法(记住我必须使用SQL Server 2008,因此它比2012年有点棘手)。
目标是按日期排序金额。任何时候类别字段在该列表中更改值,总和应该重新开始。
表格结构:
[Date], [Category], [Amount]
示例:
[Date], [Category], [Amount], [RunSumReset]
-------------------------------------------
1-Jan, catA, 10, 10
2-Jan, catA, 5, 15
3-Jan, catA, 15, 30
15-Jan, catB, 3, 3
1-Feb, catB, 6, 9
11-Feb, catA, 10, 10
12-Feb, catC, 2, 2
1-Apr, catA, 5, 5
非常感谢任何光滑的提示或技巧
答案 0 :(得分:2)
使用版本2008会使事情变得有点棘手,因为SUM
的窗口版本ORDER BY
子句不可用。
一种方法是:
WITH CTE AS (
SELECT [Date], Category, Amount,
ROW_NUMBER() OVER (ORDER BY [Date]) -
ROW_NUMBER() OVER (PARTITION BY Category
ORDER BY [Date]) AS grp
FROM mytable
)
SELECT [Date], Category, Amount, Amount + COALESCE(t.s, 0) AS RunSumReset
FROM CTE AS c1
OUTER APPLY (
SELECT SUM(c2.Amount)
FROM CTE AS c2
WHERE c2.[Date] < c1.[Date] AND
c1.Category = c2.Category AND
c1.grp = c2.grp) AS t(s)
ORDER BY [Date]
CTE
用于计算字段grp
,该字段标识具有相同Category
的连续记录的岛。 Category
更改后,grp
值也会发生变化。使用此CTE
,我们可以计算SQL Server 2012
之前版本中正常运行方式的运行总计,即使用OUTER APPLY
。
答案 1 :(得分:1)
选择当前行和第一行中具有不同类别的金额总和。在您的情况下,您需要将NULL
替换为SQL Server
支持的最短日期,例如'17530101'
:
DECLARE @t TABLE
(
category INT ,
amount INT ,
ordering INT
)
INSERT INTO @t
VALUES ( 1, 1, 1 ),
( 1, 2, 2 ),
( 1, 3, 3 ),
( 2, 4, 4 ),
( 2, 5, 5 ),
( 3, 6, 6 ),
( 1, 7, 7 ),
( 1, 8, 8 ),
( 4, 9, 9 ),
( 1, 10, 10 )
SELECT category ,
amount ,
( SELECT SUM(amount)
FROM @t
WHERE category = t.category
AND ordering <= t.ordering
AND ordering > ( SELECT ISNULL(MAX(ordering), 0)
FROM @t
WHERE category <> t.category
AND ordering < t.ordering
)
) AS sum
FROM @t t
ORDER BY t.ordering
输出:
category amount sum
1 1 1
1 2 3
1 3 6
2 4 4
2 5 9
3 6 6
1 7 7
1 8 15
4 9 9
1 10 10