4

Sample table ID: (num is a key so there wouldn't be any duplicates)

num
1
5
6
8
2
3

Desired output:
(Should be sorted and have a cumulative sum column)

num cumulative
1    1
2    3
3    6
5    11
6    17
8    25

This is one solution I got:

select a.num, sum(b.num) from ID a, ID b where b.num <= a.num group by a.num order by a.num;
varunl
  • 19,499
  • 5
  • 29
  • 47
  • AFAIK, MySQL can't really do this sort of thing. `This` being referencing previous rows. You could use a temporary table, I suppose, but it might be better doing this sort of thing clientside. – Bojangles Oct 02 '11 at 21:12
  • Just a fun problem i got while playing with mysql. Trying to use joins. – varunl Oct 02 '11 at 21:15
  • You could certainly do it with variables, common someone will certainly show the @sum answer. I'm lazy. – regilero Oct 02 '11 at 21:47
  • I didn't want to do it with variables. Just sql query. – varunl Oct 02 '11 at 21:52

4 Answers4

7

You can use a temporary variable to calculate the cumulative sum:

SELECT  a.num,
   (@s := @s + a.num) AS cumulative
FROM ID a, (SELECT @s := 0) dm
ORDER BY a.num;
The Scrum Meister
  • 29,681
  • 8
  • 66
  • 64
3

I think I figured out the solution.

Select num as n, 
       (select sum(num) from ID where num <= n)
from ID order by n;
varunl
  • 19,499
  • 5
  • 29
  • 47
  • 4
    Actually, it doesn't work if you have duplicates, i.e. 1,2,3,3,4,5, you'll get 0,1,3,3,9,13, which I don't think is what you want. – Matthew Farwell Oct 02 '11 at 22:15
  • Yup, that totally makes sense. I was looking at only unique values. Will update that in the question. – varunl Oct 02 '11 at 23:13
1

Since MySQL 8, cumulative sums are ideally calculated using window functions. In your case, run:

SELECT num, SUM(num) OVER (ORDER BY num) cumulative
FROM id
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • do u know why w/o order by it ouputs all sum not cumulative? – haneulkim May 25 '20 at 09:10
  • @Ambleu: Yes, see here: https://stackoverflow.com/questions/17664436/cumulative-sum-over-a-set-of-rows-in-mysql/52373539?noredirect=1#comment109653718_52373539 – Lukas Eder May 26 '20 at 09:44
0

as these answer i already tested in my project and actually i want to know which one is faster so i also posted this here which one is faster

declare @tmp table(ind int identity(1,1),col1 int)
insert into @tmp
select 2
union
select 4
union
select 7
union 

select 5
union
select 8
union 
select 10


 SELECT t1.col1,sum( t2.col1)
    FROM @tmp AS t1 LEFT JOIN @tmp t2 ON t1.ind>=t2.ind
    group by t1.ind,t1.col1

select t1.col1,(select sum(col1) from  @tmp as t2 where t2.ind<=t1.ind)
from @tmp as t1
Community
  • 1
  • 1
rahularyansharma
  • 11,156
  • 18
  • 79
  • 135