7

I have a table of the form

 Category      Time      Qty  
     A           1        20 
     B           2         3
     A           3        43
     A           4        20
     B           5        25

I need a running total to be calculated by category in MySQL. The result would look something like this:

 Category      Time      Qty     Cat.Total  
     A           1        20         20
     B           2         3          3
     A           3        43         63
     A           4        20         83
     B           5        25         28

Any idea how I could do this efficiently in MySQL? I have searched far and wide, but all I can find is info on how to insert one single running total in MySQL. I wonder if there's any way to use GROUP BY or a similar construct to achieve this.

2
  • Does it have to be a running total or is it ok to calculate the final total in one go? Commented Feb 17, 2011 at 17:35
  • i need running total for this @fredley Do u have any idea how to this? let's say I have the same tables as he has Commented Feb 20, 2018 at 5:09

1 Answer 1

14

You could calculate the sum in a subquery:

select  Category
,       Time
,       Qty
,       (
        select  sum(Qty) 
        from    YourTable t2 
        where   t1.Category = t2.Category 
                and t1.Time >= t2.Time
        ) as CatTotal
from    YourTable t1

Trading readability for speed, you can use a MySQL variable to hold the running sum:

select  Category
,       Time
,       Qty
,       @sum := if(@cat = Category,@sum,0) + Qty as CatTotal
,       @cat := Category
from    YourTable
cross join
        (select @cat := '', @sum := 0) as InitVarsAlias
order by
        Category
,       Time

The ordering is required for this construct to work; if you need a different order, wrap the query in a subquery:

select  Category
,       Time
,       Qty
,       CatTotal
from    (
        select  Category
        ,       Time
        ,       Qty
        ,       @sum := if(@cat = Category,@sum,0) + Qty as CatTotal
        ,       @cat := Category
        from    YourTable
        cross join
                (select @cat := '', @sum := 0) as InitVarsAlias
        order by
                Category
        ,       Time
        ) as SubQueryAlias
order by
        Time
Sign up to request clarification or add additional context in comments.

2 Comments

How well does this perform
This solution does not consider the Time column. It does work in part... but the running total with time does not work, only with category alone. -- I am still working on a solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.