How to get cumulative sum

前端 未结 16 2350
遇见更好的自我
遇见更好的自我 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:06

    You can use this simple query for progressive calculation :

    select 
       id
      ,SomeNumt
      ,sum(SomeNumt) over(order by id ROWS between UNBOUNDED PRECEDING and CURRENT ROW) as CumSrome
    from @t
    
    0 讨论(0)
  • 2020-11-22 04:06

    Without using any type of JOIN cumulative salary for a person fetch by using follow query:

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

    A CTE version, just for fun:

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

    Returns:

    id          SomeNumt    MySum
    ----------- ----------- -----------
    1           10          10
    2           12          22
    3           3           25
    4           15          40
    5           23          63
    
    0 讨论(0)
  • 2020-11-22 04:08

    Above (Pre-SQL12) we see examples like this:-

    SELECT
        T1.id, SUM(T2.id) AS CumSum
    FROM 
        #TMP T1
        JOIN #TMP T2 ON T2.id < = T1.id
    GROUP BY
        T1.id
    

    More efficient...

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

    Lets first create a table with dummy data -->

    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 
    

    here I am joining same table (SELF Joining)

    Select c1.ID, c1.SomeValue, c2.SomeValue
    From CumulativeSum c1,  CumulativeSum c2
    Where c1.id >= c2.ID
    Order By c1.id Asc
    

    RESULT :

    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
    

    here we go now just sum the Somevalue of t2 and we`ll get the ans

    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 and above(Much better perform)

    Select c1.ID, c1.SomeValue, 
    SUM (SomeValue) OVER (ORDER BY c1.ID )
    From CumulativeSum c1
    Order By c1.id Asc
    

    Desired Result

    ID  SomeValue   CumlativeSumValue
    1   10          10
    2   2           12
    3   6           18
    4   10          28
    
    Drop Table CumulativeSum
    

    Clear the dummytable

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

    Late answer but showing one more possibility...

    Cumulative Sum generation can be more optimized with the CROSS APPLY logic.

    Works better than the INNER JOIN & OVER Clause when analyzed the actual query plan ...

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