当前行的累计值+前一行的总和

时间:2012-10-01 07:01:03

标签: sql sql-server sql-server-2008 cumulative-sum

如何从表中转换表中的列:

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。你会采用什么方法。

10 个答案:

答案 0 :(得分:13)

像这样:

;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

这是a live demo

答案 1 :(得分:8)

我通常会避免尝试这样做,但以下内容符合您的要求:

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

答案 2 :(得分:6)

不确定这是否是最佳的,但是如何(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

答案 3 :(得分:3)

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;

答案 4 :(得分:0)

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;

答案 5 :(得分:0)

尝试以下脚本,

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 :(得分:0)

使用SQL SERVER?所以

假设您有一个包含3列C_1,C_2,C_3并由C_1排序的表。 只需使用[Over(按C_1排序)]为C_3的总和添加一列:

选择C_1,C_2,C_3,总和(C_3)结束(按C_1排序)

如果您也想要行号,请以相同的方式进行操作:

选择 Row_Number()以上(按C_1排序),C_1,C_2,C_3,和(C_3)以上(按C_1排序)

答案 7 :(得分:0)

如果您使用的是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

答案 8 :(得分:-1)

这将基于列的分组对列的累积求和。

请参见下面的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

答案 9 :(得分:-2)

您可以使用以下简单的select语句来实现相同的

SELECT COLUMN_A, COLUMN_B, 
(SELECT SUM(COLUMN_B) FROM #TBL T2 WHERE T2.ID  <= T1.ID) as SumofPreviousRow FROM #TBL T1;