Back to articles list Articles Cookbook
7 minutes read

What Is a SQL Running Total and How Do You Compute It?

The SQL running total is a very common pattern, used frequently in finance and in trend analysis. In this article, you’ll learn what a running total is and how to write a SQL query to compute it.

The best way to learn SQL is through practice. LearnSQL.com offers over 30 interactive SQL courses at various level of difficulty. Each course is interactive: there is a little bit of reading, followed by an exercise to practice what you've just read. With each exercise solved you gain confidence in your SQL skills. Sign up now for free!

What’s a SQL Running Total?

In SQL, a running total is the cumulative sum of the previous numbers in a column. Look at the example below, which presents the daily registration of users for an online shop:

registration_dateregistered_userstotal_users
2020-03-053232
2020-03-061547
2020-03-07653

The first column shows the date. The second column shows the number of users who registered on that date. The third column, total_users, sums the total number of registered users on that day.

For example, on the first day (2020-03-05), 32 users registered and the total value of registered users was 32. The next day (2020-03-06) 15 users registered; the total_users value became 47 (32+15). The third day (2020-03-07), six users registered and the total_users value was 53. In other words, total_users is a running value that changes from day to day. It is the total number of users on each day.

The next example uses the total_revenue column to deal with company revenue in a similar way. Look at the table below:

daterevenuetotal_revenue
2020-04-02125 000125 000
2020-04-03125 000250 000
2020-04-0420 500270 500
2020-04-05101 000371 500

For each day, the total_revenue column is calculating the amount of revenue generated up to the given day. On 2020-04-04, the company achieved a total revenue of $270,500 because that is the sum of all revenues from 2020-04-02 to 2020-04-04.

Relational databases (like SQL Server, Oracle, PostgreSQL, and MySQL) and even non-relational engines like Hive and Presto provide window functions that allow us to calculate a running total. To learn about window functions, I recommend the interactive Window Functions course. It contains over 200 exercises to learn window functions by using them.

Next, we’ll talk about the SQL query that builds such a sum and learn more about window functions.

How to Compute a Cumulative Sum in SQL

If you would like to compute running total in SQL, you need to be familiar with the window functions provided by your database. Window functions operate on a set of rows and return an aggregate value for each row in the result set.

The syntax of the SQL window function that computes a cumulative sum across rows is:

window_function ( column ) 
OVER ( [ PARTITION BY partition_list ] [ ORDER BY order_list] )

It’s mandatory to use the OVER clause in a window function, but the arguments in this clause are optional. We will discuss them in the next paragraphs of this article.

Example 1

In this example, we will calculate the total running sum of the registered users each day.

registration_dateregistered_users
2020-03-0532
2020-03-0615
2020-03-076

This query ...

SELECT registration_date,registred_users,
  SUM(registred_users) OVER (ORDER BY registration_date)
  AS total_users
FROM registration;

… selects the registration date for all users. We also need the sum of all users for each day, starting from the first given day (2020-03-05) to the day in that row.

This is the result set:

registration_dateregistered_userstotal_users
2020-03-055757
2020-03-062784
2020-03-0716100

To calculate the running total, we use the SUM() aggregate function and put the column registered_users as the argument; we want to obtain the cumulative sum of users from this column.

The next step is to use the OVER clause. In our example, this clause has one argument: ORDER BY registration_date. The rows of the result set are sorted according to this column (registration_date). For each value in the registration_date column, the total sum of the previous column values is computed (i.e. the sum of the number of users before the date in the current row) and the current value (i.e. users registered on the day of the current row) is added to it.

Notice that the total sum is shown in the new column, which we named total_users.

In the first step (the registration date 2020-03-05), we have 57 registered users. The sum of users registered this day is the same 57. In the next step, we add to this total value (57). What do we add? The number of users registered on the current date (2020-03-06), which is 27; this gives us a running total of 84. In the last row of the result set (for the last registration date, 2020-03-07) the running total is 100.

Thanks to SQL window functions, it is easy to find the cumulative total number of users during a given period of time. For example, during 2020-03-05 – 2020-03-06, the total number of registered users was 84.

Example 2

In the second example, we’ll go into more details about users. We’ll show users with their countries. Look at the table below:

countryregistration_dateregistered_users
England2020-03-0525
England2020-03-0612
England2020-03-0710
Poland2020-03-0532
Poland2020-03-0615
Poland2020-03-076

Notice that for each day we have the number of users for each country shown separately. In this example, we will compute a separate cumulative sum of registered users for each country.

This query ...

SELECT country, registration_date,registred_users,
  SUM(registred_users) 
  OVER (PARTITION BY country ORDER BY registration_date)
  AS total_users
FROM registration;

… calculates the sum of users for each day, first for users from England and then for users from Poland.

Here’s the result set:

countryregistration_dateregistered_userstotal_users
England2020-03-052525
England2020-03-061237
England2020-03-071047
Poland2020-03-053232
Poland2020-03-061547
Poland2020-03-07653

For each country, each registration day gets a running total. The PARTITION BY clause in the OVER clause has the column country as its argument. This partitions rows by country, allowing SQL to compute a running total for that country only (instead of both countries together). Thus, in England from 2020-03-05 to 2020-03-07, we have a total of 47 users. For the same period in Poland, the total of registered users was 53.

Example 3

In the last example, we’ll analyze the data in the competition table, which stores the columns game_id, gamer_id, game_level, competition_date, and score.

game_idgame_levelgamer_idcompetition_datescore
1342020-04-024
1242020-04-035
1142020-04-042
1352020-04-021
1252020-04-032
2372020-04-074
2272020-04-086
2172020-04-072
2362020-04-081
2262020-04-091
2382020-04-072

We need to check each gamer’s total cumulative score for each day in two different games. Look at the query below, which creates this running total:

SELECT game_id,game_level,gamer_id,competition_date,score,
  SUM(score)
  OVER (PARTITION BY game_id, gamer_id 
        ORDER BY competition_date)
  AS total_score
FROM competition;

The result:

game_idgame_levelgamer_idcompetition_datescoretotal_score
1342020-04-0244
1242020-04-0359
1142020-04-04211
1352020-04-0211
1252020-04-0323
2362020-04-0711
2262020-04-0812
2372020-04-0744
2272020-04-08610
2172020-04-09212
2382020-04-0722

In this result table, we can read that the gamer with ID=4 starts from a score of 4 and finishes with a total score of 11. The best was the gamer with ID=7, who finished with a total score of 12.

Once again, in the OVER clause we use PARTITION BY. This time, we use a list of columns (game_id, gamer_id). This allows us to create two partitions: one for game 1 and one for game 2.

Next, rows were divided by gamer_id for each game. In game 1, we have the gamers 4 and 5; in game 2, we have the gamers 6, 7, and 8. Among each group (a given gamer plays in a given game), rows are sorted by competition_date and the score from each day is summed. In each group, we can observe each gamer’s changing score in a given game.

How Will You Use SQL Running Totals?

Using a running total value in SQL reports can be very handy, especially for financial specialists. Therefore, it is worthwhile to know what a cumulative sum is and how to use SQL window functions to create one. This article presented a few selected use cases. For more about window functions, check out our article SQL Window Function Example With Explanations or the LearnSQL course Window Functions.