Library code snippets

Running total in an SQL query

There are no standard functions in either MySQL or MS SQL Server to return a running total for an SQL query. It is, however, relatively easy using the CROSS JOIN statement. In order to do this, use the following SQL:

SELECT column_names, SUM(b.running_total_column) AS RunningTotal
FROM table_name a CROSS JOIN table_name b
WHERE (b.unique_id <= a.unique_id)
GROUP BY a.unique_id,a.running_total_column

Note that the performance of this query can be improved by adding a clustered index on the unique_id field. Also, if you include extra statements in the WHERE clause, you need to limit the query for both the a and b tables (ie instead of WHERE a.id < 100, you need WHERE a.id < 100 AND b.id < 100).

An alternative (and more efficient) method is the following stored procedure (but obviously you do not have this option in MySQL).

CREATE TABLE #TableName (unique_id int, running_total_column int, RunningTotal int)

DECLARE @unique_id int,
@running_total_column int,
@RunningTotal int

SET @RunningTotal = 0

DECLARE rt_cursor CURSOR FOR
   SELECT unique_id, running_total_column FROM tablename

OPEN rt_cursor

FETCH NEXT FROM rt_cursor INTO @unique_id,@running_total_column

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @RunningTotal = @RunningTotal + @running_total_column
  INSERT #TableName VALUES (@unique_id,@running_total_column,@RunningTotal)
FETCH NEXT FROM rt_cursor INTO @unique_id,@running_total_column
END

CLOSE rt_cursor
DEALLOCATE rt_cursor

SELECT * FROM #TableName ORDER BY unique_id

DROP TABLE #TableName

As with all the code, you will need to change the text in italics to the columns / table names you require.

Comments

  1. 12 Aug 2002 at 00:05

    I am trying to create a running total on a datetime function.  I don't have a unique id? but at present I can do a count on the number of people who registered for an event in a day by using CONVERT.


    However, I want it to display a running total, rather than a count of the number of people who register per day, but I can't seem to do this.  
    Please help!!  Also the query relates to more than 1 table.
    This is an example:



    select    CONVERT(datetime,
               (CONVERT(varchar,DAY(sea.date))+'/'
               +CONVERT(varchar,MONTH(sea.date))+'/'
               +CONVERT(varchar,YEAR(sea.date))),
                               105) AS RegistrationDate
           
       , COUNT  (CONVERT(datetime,
               (CONVERT(varchar,DAY(sea.date))+'/'
               +CONVERT(varchar,MONTH(sea.date))+'/'
               +CONVERT(varchar,YEAR(sea.date))),
                               105)) As RegNos
    from    table1 sea
       INNER JOIN table2 scc ON sea.number1= scc.number5
       LEFT JOIN table3 s ON s.number2 = scc.number6
       INNER JOIN table4 con ON con.number3 = scc.number7
       LEFT JOIN table5 org ON org.number4= con.number8
    WHERE    blah = 'blah'
    AND    blah = 'blah'
    AND    blah = 'blah'
    AND    blah = 'blah'
    GROUP BY CONVERT(datetime,
               (CONVERT(varchar,DAY(sea.date))+'/'
               +CONVERT(varchar,MONTH(sea.date))+'/'
               +CONVERT(varchar,YEAR(sea.date))),
                               105))

  2. 01 Jan 1999 at 00:00

    This thread is for discussions of Running total in an SQL query.

Leave a comment

Sign in or Join us (it's free).

James Crowley James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audience ...

Related podcasts

  • Rocky Lhotka on Data Access Mania, LINQ and CSLA.NET

    Scott talks with developer and author Rockford Lhotka about the attack of the DALs (Data Access Layers). How can we put LINQ to SQL, LINQ to Entities and classic multi-tiered design all into a larger context? What's the right strategy for your data access needs? Scott's got questions and Rocky's ...

Want to stay in touch with what's going on? Follow us on twitter!