Reputation: 13534
I am trying to write a SQL to calculate running total with in each group in the below input. Just wondering how can I do it using MySQL. I am aware of how to do it in regular SQL using analytic functions but not in MySQL. Could you share your thoughts on how to implement it.
SQL Fiddle : http://sqlfiddle.com/#!9/59366d/19
SQL using window function :
SELECT e.Id,
SUM( e.Salary ) OVER( PARTITION BY e.Id ORDER BY e.Month ) AS cumm_sal
FROM Employee e
LEFT JOIN
(
SELECT Id,MAX(Month) AS maxmonth
FROM Employee
GROUP BY Id
) emax
ON e.Id = emax.Id
WHERE e.Month != emax.maxmonth
ORDER BY e.Id,e.Month DESC;
Input :
Create table Employee (Id int, Month int, Salary int);
insert into Employee (Id, Month, Salary) values ('1', '1', '20');
insert into Employee (Id, Month, Salary) values ('2', '1', '20');
insert into Employee (Id, Month, Salary) values ('1', '2', '30');
insert into Employee (Id, Month, Salary) values ('2', '2', '30');
insert into Employee (Id, Month, Salary) values ('3', '2', '40');
insert into Employee (Id, Month, Salary) values ('1', '3', '40');
insert into Employee (Id, Month, Salary) values ('3', '3', '60');
insert into Employee (Id, Month, Salary) values ('1', '4', '60');
insert into Employee (Id, Month, Salary) values ('3', '4', '70');
Output :
| Id | Month | Salary |
|----|-------|--------|
| 1 | 3 | 90 |
| 1 | 2 | 50 |
| 1 | 1 | 20 |
| 2 | 1 | 20 |
| 3 | 3 | 100 |
| 3 | 2 | 40 |
Upvotes: 1
Views: 2524
Reputation: 1269623
In MySQL, the most efficient approach is to use variables:
select e.*,
(@s := if(@id = e.id, @s + salary,
if(@id := e.id, salary, salary)
)
) as running_salary
from (select e.*
from employee e
order by e.id, e.month
) e cross join
(select @id := -1, @s := 0) params;
You can also do this with a correlated subquery:
select e.*,
(select sum(e2.salary)
from employee e2
where e2.id = e.id and e2.month <= e.month
) as running_salary
from employee e;
Upvotes: 5