declare @t table
(
id int,
SomeNumt int
)
insert into @t
select 1,10
union
select 2,12
union
select 3,3
union
select 4,15
union
select 5,23
select * from @t
以上选择将返回以下内容。
id SomeNumt
1 10
2 12
3 3
4 15
5 23
我如何获得以下
id srome CumSrome
1 10 10
2 12 22
3 3 25
4 15 40
5 23 63
答案 0 :(得分:189)
select t1.id, t1.SomeNumt, SUM(t2.SomeNumt) as sum
from @t t1
inner join @t t2 on t1.id >= t2.id
group by t1.id, t1.SomeNumt
order by t1.id
<强>输出强>
| ID | SOMENUMT | SUM |
-----------------------
| 1 | 10 | 10 |
| 2 | 12 | 22 |
| 3 | 3 | 25 |
| 4 | 15 | 40 |
| 5 | 23 | 63 |
编辑:这是一种适用于大多数数据库平台的通用解决方案。如果您的特定平台有更好的解决方案(例如,gareth's),请使用它!
答案 1 :(得分:161)
最新版本的SQL Server(2012)允许以下内容。
SELECT
RowID,
Col1,
SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
或
SELECT
GroupID,
RowID,
Col1,
SUM(Col1) OVER(PARTITION BY GroupID ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
这更快。分区版本在34秒内完成超过500万行。
感谢Peso,他对另一个答案中提到的SQL Team线程发表了评论。
答案 2 :(得分:21)
对于SQL Server 2012以上,它可能很简单:
TypeError: Cannot read property 'status' of undefined
因为SELECT id, SomeNumt, sum(SomeNumt) OVER (ORDER BY id) as CumSrome FROM @t
的{{1}}条款默认表示ORDER BY
用于窗口框架(&#34;一般说明&#34;在https://msdn.microsoft.com/en-us/library/ms189461.aspx)
答案 3 :(得分:11)
CTE版本,只是为了好玩:
;
WITH abcd
AS ( SELECT id
,SomeNumt
,SomeNumt AS MySum
FROM @t
WHERE id = 1
UNION ALL
SELECT t.id
,t.SomeNumt
,t.SomeNumt + a.MySum AS MySum
FROM @t AS t
JOIN abcd AS a ON a.id = t.id - 1
)
SELECT * FROM abcd
OPTION ( MAXRECURSION 1000 ) -- limit recursion here, or 0 for no limit.
返回:
id SomeNumt MySum
----------- ----------- -----------
1 10 10
2 12 22
3 3 25
4 15 40
5 23 63
答案 4 :(得分:11)
让我们首先创建一个包含虚拟数据的表 - &gt;
Create Table CUMULATIVESUM (id tinyint , SomeValue tinyint)
**Now let put some data in the table**
Insert Into CUMULATIVESUM
Select 1, 10 union
Select 2, 2 union
Select 3, 6 union
Select 4, 10
在这里我加入了同桌(SELF Joining)
Select c1.ID, c1.SomeValue, c2.SomeValue
From CumulativeSum c1, CumulativeSum c2
Where c1.id >= c2.ID
Order By c1.id Asc
结果:
ID SomeValue SomeValue
1 10 10
2 2 10
2 2 2
3 6 10
3 6 2
3 6 6
4 10 10
4 10 2
4 10 6
4 10 10
这里我们现在就把t2的Somevalue加起来,我们就得到了
Select c1.ID, c1.SomeValue, Sum(c2.SomeValue) CumulativeSumValue
From CumulativeSum c1, CumulativeSum c2
Where c1.id >= c2.ID
Group By c1.ID, c1.SomeValue
Order By c1.id Asc
FOR SQL SERVER 2012及更高版本(更好的表现)
Select c1.ID, c1.SomeValue,
SUM (SomeValue) OVER (ORDER BY c1.ID )
From CumulativeSum c1
Order By c1.id Asc
期望的结果
ID SomeValue CumlativeSumValue
1 10 10
2 2 12
3 6 18
4 10 28
Drop Table CumulativeSum
清除虚拟表格
答案 5 :(得分:5)
迟到的答案,但又显示了一种可能性......
使用CROSS APPLY
逻辑可以更优化累积和生成。
效果优于INNER JOIN
&amp;分析实际查询计划时OVER Clause
...
/* Create table & populate data */
IF OBJECT_ID('tempdb..#TMP') IS NOT NULL
DROP TABLE #TMP
SELECT * INTO #TMP
FROM (
SELECT 1 AS id
UNION
SELECT 2 AS id
UNION
SELECT 3 AS id
UNION
SELECT 4 AS id
UNION
SELECT 5 AS id
) Tab
/* Using CROSS APPLY
Query cost relative to the batch 17%
*/
SELECT T1.id,
T2.CumSum
FROM #TMP T1
CROSS APPLY (
SELECT SUM(T2.id) AS CumSum
FROM #TMP T2
WHERE T1.id >= T2.id
) T2
/* Using INNER JOIN
Query cost relative to the batch 46%
*/
SELECT T1.id,
SUM(T2.id) CumSum
FROM #TMP T1
INNER JOIN #TMP T2
ON T1.id > = T2.id
GROUP BY T1.id
/* Using OVER clause
Query cost relative to the batch 37%
*/
SELECT T1.id,
SUM(T1.id) OVER( PARTITION BY id)
FROM #TMP T1
Output:-
id CumSum
------- -------
1 1
2 3
3 6
4 10
5 15
答案 6 :(得分:3)
Select *, (Select SUM(SOMENUMT)
From @t S
Where S.id <= M.id)
From @t M
答案 7 :(得分:2)
这篇优秀文章提供了更快的CTE实施: http://weblogs.sqlteam.com/mladenp/archive/2009/07/28/SQL-Server-2005-Fast-Running-Totals.aspx
此线程中的问题可以表示如下:
DECLARE @RT INT
SELECT @RT = 0
;
WITH abcd
AS ( SELECT TOP 100 percent
id
,SomeNumt
,MySum
order by id
)
update abcd
set @RT = MySum = @RT + SomeNumt
output inserted.*
DECLARE @RT INT
SELECT @RT = 0
;
WITH abcd
AS ( SELECT TOP 100 percent
id
,SomeNumt
,MySum
order by id
)
update abcd
set @RT = MySum = @RT + SomeNumt
output inserted.*
答案 8 :(得分:1)
创建表格后
select
A.id, A.SomeNumt, SUM(B.SomeNumt) as sum
from @t A, @t B where A.id >= B.id
group by A.id, A.SomeNumt
order by A.id
答案 9 :(得分:1)
上面(Pre-SQL12)我们看到这样的例子: -
SELECT
T1.id, SUM(T2.id) AS CumSum
FROM
#TMP T1
JOIN #TMP T2 ON T2.id < = T1.id
GROUP BY
T1.id
效率更高......
SELECT
T1.id, SUM(T2.id) + T1.id AS CumSum
FROM
#TMP T1
JOIN #TMP T2 ON T2.id < T1.id
GROUP BY
T1.id
答案 10 :(得分:0)
试试这个
select
t.id,
t.SomeNumt,
sum(t.SomeNumt) Over (Order by t.id asc Rows Between Unbounded Preceding and Current Row) as cum
from
@t t
group by
t.id,
t.SomeNumt
order by
t.id asc;
答案 11 :(得分:0)
试试这个:
CREATE TABLE #t(
[name] varchar NULL,
[val] [int] NULL,
[ID] [int] NULL
) ON [PRIMARY]
insert into #t (id,name,val) values
(1,'A',10), (2,'B',20), (3,'C',30)
select t1.id, t1.val, SUM(t2.val) as cumSum
from #t t1 inner join #t t2 on t1.id >= t2.id
group by t1.id, t1.val order by t1.id
答案 12 :(得分:0)
SQL解决方案,它结合了“无限制前进和当前行之间的行”#34;和&#34; SUM&#34;完成了我想要实现的目标。 非常感谢你!
如果它可以帮助任何人,这是我的情况。每当制造商被发现为&#34; Some Maker&#34;时,我想在列中累积+1。 (例)。如果没有,则没有增量但显示先前的增量结果。
所以这段SQL:
SUM( CASE [rmaker] WHEN 'Some Maker' THEN 1 ELSE 0 END)
OVER
(PARTITION BY UserID ORDER BY UserID,[rrank] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Cumul_CNT
允许我得到这样的东西:
User 1 Rank1 MakerA 0
User 1 Rank2 MakerB 0
User 1 Rank3 Some Maker 1
User 1 Rank4 Some Maker 2
User 1 Rank5 MakerC 2
User 1 Rank6 Some Maker 3
User 2 Rank1 MakerA 0
User 2 Rank2 SomeMaker 1
上述说明:它开始计算&#34;某个制造商&#34; 0,找到了一些Maker,我们做+1。对于用户1,发现了MakerC,所以我们不做+1,而是将Some Maker的垂直计数固定为2直到下一行。 分区是由用户进行的,因此当我们更改用户时,累计计数会回到零。
我在工作,我不希望这个答案有任何优点,只要说谢谢并展示我的例子,以防有人处于同样的情况。我试图将SUM和PARTITION结合起来,但结合了惊人的语法&#34;在无限制的前进行和当前的行之间行驶#34;完成任务。
谢谢! Groaker
答案 13 :(得分:0)
使用跟随查询不使用任何类型的JOIN累积工资:
SELECT * , (
SELECT SUM( salary )
FROM `abc` AS table1
WHERE table1.ID <= `abc`.ID
AND table1.name = `abc`.Name
) AS cum
FROM `abc`
ORDER BY Name
答案 14 :(得分:0)
您可以使用此简单查询进行渐进式计算:
select
id
,SomeNumt
,sum(SomeNumt) over(order by id ROWS between UNBOUNDED PRECEDING and CURRENT ROW) as CumSrome
from @t
答案 15 :(得分:0)
对于Ex:如果您有一个包含两列的表,其中第一列是ID,第二列是数字,并希望找出累积和。
SELECT ID,Number,SUM(Number)OVER(ORDER BY ID) FROM T