How to get cumulative sum

前端 未结 16 2351
遇见更好的自我
遇见更好的自我 2020-11-22 03:32
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         


        
相关标签:
16条回答
  • 2020-11-22 04:10

    The SQL solution wich combines "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" and "SUM" did exactly what i wanted to achieve. Thank you so much!

    If it can help anyone, here was my case. I wanted to cumulate +1 in a column whenever a maker is found as "Some Maker" (example). If not, no increment but show previous increment result.

    So this piece of 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
    

    Allowed me to get something like this:

    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  
    

    Explanation of above: It starts the count of "some maker" with 0, Some Maker is found and we do +1. For User 1, MakerC is found so we dont do +1 but instead vertical count of Some Maker is stuck to 2 until next row. Partitioning is by User so when we change user, cumulative count is back to zero.

    I am at work, I dont want any merit on this answer, just say thank you and show my example in case someone is in the same situation. I was trying to combine SUM and PARTITION but the amazing syntax "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" completed the task.

    Thanks! Groaker

    0 讨论(0)
  • 2020-11-22 04:13
    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
    

    SQL Fiddle example

    Output

    | ID | SOMENUMT | SUM |
    -----------------------
    |  1 |       10 |  10 |
    |  2 |       12 |  22 |
    |  3 |        3 |  25 |
    |  4 |       15 |  40 |
    |  5 |       23 |  63 |
    

    Edit: this is a generalized solution that will work across most db platforms. When there is a better solution available for your specific platform (e.g., gareth's), use it!

    0 讨论(0)
  • 2020-11-22 04:14

    The latest version of SQL Server (2012) permits the following.

    SELECT 
        RowID, 
        Col1,
        SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
    FROM tablehh
    ORDER BY RowId
    

    or

    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
    

    This is even faster. Partitioned version completes in 34 seconds over 5 million rows for me.

    Thanks to Peso, who commented on the SQL Team thread referred to in another answer.

    0 讨论(0)
  • 2020-11-22 04:14

    There is a much faster CTE implementation available in this excellent post: http://weblogs.sqlteam.com/mladenp/archive/2009/07/28/SQL-Server-2005-Fast-Running-Totals.aspx

    The problem in this thread can be expressed like this:

        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.*
    

    0 讨论(0)
  • 2020-11-22 04:19

    Try this

    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;
    
    0 讨论(0)
  • 2020-11-22 04:22

    Once the table is created -

    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
    
    0 讨论(0)
提交回复
热议问题