【问题标题】: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
    

    这里是a live demo

    【讨论】:

      【解决方案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
                    

                    【讨论】:

                    • IT 将根据列的累积总和的分组来工作
                    【解决方案10】:

                    你可以使用下面的简单选择语句来做同样的事情

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

                    【讨论】:

                      猜你喜欢
                      • 2020-06-27
                      • 2019-09-22
                      • 2021-10-16
                      • 2021-03-23
                      • 2020-05-10
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-07-09
                      • 2017-10-02
                      相关资源
                      最近更新 更多