【问题标题】:Cumulating value of current row + sum of previous rows当前行的累加值 + 前行的总和
【发布时间】:2012-09-22 00:53:31
【问题描述】:
你将如何从这个转换表中的列:
ColumnA ColumnB
2 a
3 b
4 c
5 d
1 a
到这里:
ColumnA ColumnB
3 a
6(=3+3) b
10(=4+3+3) c
15(=5+4+3+3) d
我有兴趣看看 esp。你会选择什么方法。
【问题讨论】:
标签:
sql
sql-server
sql-server-2008
cumulative-sum
【解决方案1】:
像这样:
;WITH cte
AS
(
SELECT ColumnB, SUM(ColumnA) asum
FROM @t
gROUP BY ColumnB
), cteRanked AS
(
SELECT asum, ColumnB, ROW_NUMBER() OVER(ORDER BY ColumnB) rownum
FROM cte
)
SELECT (SELECT SUM(asum) FROM cteRanked c2 WHERE c2.rownum <= c1.rownum),
ColumnB
FROM cteRanked c1;
这应该给你:
ColumnA ColumnB
3 a
6 b
10 c
15 d
【解决方案2】:
我通常会避免尝试这样做,但以下内容符合您的要求:
declare @T table (ColumnA int,ColumnB char(1))
insert into @T(ColumnA,ColumnB) values
(2 , 'a'),
(3 , 'b'),
(4 , 'c'),
(5 , 'd'),
(1, 'a')
;With Bs as (
select distinct ColumnB from @T
)
select
SUM(t.ColumnA),b.ColumnB
from
Bs b
inner join
@T t
on
b.ColumnB >= t.ColumnB
group by
b.ColumnB
结果:
ColumnB
----------- -------
3 a
6 b
10 c
15 d
对于小型数据集,这会很好。但对于较大的数据集,请注意表格的最后一行依赖于获取原始表格全部内容的SUM。
【解决方案3】:
不确定这是否最佳,但 (SQL Fiddle) 怎么样:
SELECT x.A + COALESCE(SUM(y.A),0) ColumnA, x.ColumnB
FROM
(
SELECT SUM(ColumnA) A, ColumnB
FROM myTable
GROUP BY ColumnB
) x
LEFT OUTER JOIN
(
SELECT SUM(ColumnA) A, ColumnB
FROM myTable
GROUP BY ColumnB
) y ON y.ColumnB < x.ColumnB
GROUP BY x.ColumnB, x.A
【解决方案4】:
create table #T
(
ID int primary key,
ColumnA int,
ColumnB char(1)
);
insert into #T
select row_number() over(order by ColumnB),
sum(ColumnA) as ColumnA,
ColumnB
from YourTable
group by ColumnB;
with C as
(
select ID,
ColumnA,
ColumnB
from #T
where ID = 1
union all
select T.ID,
T.ColumnA + C.ColumnA,
T.ColumnB
from #T as T
inner join C
on T.ID = C.ID + 1
)
select ColumnA,
ColumnB
from C
option (maxrecursion 0);
drop table #T;
【解决方案5】:
试试下面的脚本,
DECLARE @T TABLE(ColumnA INT, ColumnB VARCHAR(50));
INSERT INTO @T VALUES
(2, 'a'),
(3, 'b'),
(4, 'c'),
(5, 'd'),
(1, 'a');
SELECT SUM(ColumnA) OVER(ORDER BY ColumnB) AS ColumnA,ColumnB
FROM ( SELECT SUM(ColumnA) AS ColumnA,ColumnB
FROM @T GROUP BY ColumnB )T
【解决方案6】:
使用 SQL 服务器?所以
假设您有一个包含 3 列 C_1、C_2、C_3 并按 C_1 排序的表。
只需使用 [Over (Order By C_1)] 为 C_3 的总和添加一列:
选择 C_1, C_2, C_3, Sum(C_3) Over (Order By C_1)
如果你也想要行号,用同样的方法:
选择 Row_Number() Over (Order By C_1), C_1, C_2, C_3, Sum(C_3) Over (Order By C_1)
【解决方案7】:
DECLARE @t TABLE(ColumnA INT, ColumnB VARCHAR(50));
INSERT INTO @t VALUES
(2, 'a'),
(3 , 'b'),
(4 , 'c'),
(5 , 'd'),
(1 , 'a');
;WITH cte
AS
(
SELECT ColumnB, sum(ColumnA) value,ROW_NUMBER() OVER(ORDER BY ColumnB) sr_no FROM @t group by ColumnB
)
SELECT ColumnB
,SUM(value) OVER ( ORDER BY ColumnB ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
FROM cte c1;
【解决方案8】:
如果您使用的是 SQL Server 2012 或更高版本,那么这将产生所需的结果。
DECLARE @t TABLE(
ColumnA int,
ColumnB varchar(50)
);
INSERT INTO @t VALUES
(2,'a'),
(3,'b'),
(4,'c'),
(5,'d'),
(1,'a');
SELECT
SUM(ColumnA) OVER (ORDER BY ColumnB ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS ColumnA,
ColumnB
FROM (
SELECT
ColumnB,
SUM(ColumnA) AS ColumnA
FROM @t
GROUP BY ColumnB
) DVTBL
ORDER BY ColumnB
【解决方案9】:
这将基于对列的累积总和进行分组。
查看下面的 SQL
SELECT product,
product_group,
fiscal_year,
Sum(quantity) OVER ( partition BY fiscal_year,a.product_group ORDER BY a.posting_date, a.product_group rows 100000000 PRECEDING) AS quantity
FROM report
WHERE
order by b.fiscal_year DESC
【解决方案10】:
你可以使用下面的简单选择语句来做同样的事情
SELECT COLUMN_A, COLUMN_B,
(SELECT SUM(COLUMN_B) FROM #TBL T2 WHERE T2.ID <= T1.ID) as SumofPreviousRow FROM #TBL T1;