In this previous post, I show how to calculate a running total in SQL using window functions. In the example, I calculated the running total of the daily amount of payments.
In this post, I want to get the daily running total over the month as well as the percentage of this running total over the month total.
Month | Amount | Running Total | Running Total Percent |
---|---|---|---|
1 | 1 | 1 | 5.9% |
1 | 13 | 14 | 82.4% |
1 | 1 | 15 | 88.2% |
1 | 2 | 17 | 100.0% |
2 | 4 | 4 | 26.7% |
2 | 19 | 23 | 60.5% |
2 | 15 | 38 | 100.0% |
3 | 4 | 4 | 18.2% |
3 | 18 | 22 | 100.0% |
I create a CTE where I calculate the payments amount per day. I also add a column with the month using the data_part()
function on the payment date.
WITH daily_amount AS (
SELECT
payment_date::date
, date_part('month', payment_date) AS month
, SUM(amount) AS amount
FROM
payment
GROUP BY
payment_date::date
, date_part('month', payment_date)
)
Then, from this CTE, I create another one that returns the monthly total and the running total over each month.
To do so, I use a window function with a PARTITION BY month
statement that partitions my data on the month. Because I partitioned my data, when I use the ROWS UNBOUNDED PRECEDING
statement, only all the amounts from the beginning of the current month are added.
monthly_running_total AS (
SELECT
payment_date
, month
, amount
, SUM(amount) OVER(PARTITION BY month) AS monthly_total
, SUM(amount) OVER(PARTITION BY month ORDER BY payment_date ROWS UNBOUNDED PRECEDING) AS running_total
FROM
daily_amount
)
Finally, I execute a SELECT
statement on this CTE where I calculate the percentage of the running total over the month's total:
\(running\ total\ percent = \frac{running\ total}{month\ total}\times100\)
ROUND(running_total * 100 / monthly_total, 1) || '%' AS running_percent
Here's the final query:
WITH daily_amount AS (
SELECT
payment_date::date
, date_part('month', payment_date) AS month
, SUM(amount) AS amount
FROM
payment
GROUP BY
payment_date::date
, date_part('month', payment_date)
), monthly_running_total AS (
SELECT
payment_date
, month
, amount
, SUM(amount) OVER(PARTITION BY month) AS monthly_total
, SUM(amount) OVER(PARTITION BY month ORDER BY payment_date ROWS UNBOUNDED PRECEDING) AS running_total
FROM
daily_amount
)
SELECT
payment_date
, month
, amount
, monthly_total
, running_total
, ROUND(running_total * 100 / monthly_total, 1) || '%' AS running_percent
FROM
monthly_running_total
;
The returned results set looks like this:
payment_date | month | amount | monthly_total | running_total | running_percent
--------------+-------+---------+---------------+---------------+-----------------
2007-02-14 | 2 | 116.73 | 8351.84 | 116.73 | 1.4%
2007-02-15 | 2 | 1188.92 | 8351.84 | 1305.65 | 15.6%
2007-02-16 | 2 | 1154.18 | 8351.84 | 2459.83 | 29.5%
2007-02-17 | 2 | 1188.17 | 8351.84 | 3648.00 | 43.7%
2007-02-18 | 2 | 1275.98 | 8351.84 | 4923.98 | 59.0%
2007-02-19 | 2 | 1290.90 | 8351.84 | 6214.88 | 74.4%
2007-02-20 | 2 | 1219.09 | 8351.84 | 7433.97 | 89.0%
2007-02-21 | 2 | 917.87 | 8351.84 | 8351.84 | 100.0%
2007-03-01 | 3 | 2808.24 | 23886.56 | 2808.24 | 11.8%
2007-03-02 | 3 | 2550.05 | 23886.56 | 5358.29 | 22.4%
2007-03-16 | 3 | 299.28 | 23886.56 | 5657.57 | 23.7%
2007-03-17 | 3 | 2442.16 | 23886.56 | 8099.73 | 33.9%
2007-03-18 | 3 | 2701.76 | 23886.56 | 10801.49 | 45.2%
2007-03-19 | 3 | 2617.69 | 23886.56 | 13419.18 | 56.2%
2007-03-20 | 3 | 2669.89 | 23886.56 | 16089.07 | 67.4%
2007-03-21 | 3 | 2868.27 | 23886.56 | 18957.34 | 79.4%
2007-03-22 | 3 | 2586.79 | 23886.56 | 21544.13 | 90.2%
2007-03-23 | 3 | 2342.43 | 23886.56 | 23886.56 | 100.0%
2007-04-05 | 4 | 273.36 | 28559.46 | 273.36 | 1.0%
2007-04-06 | 4 | 2077.14 | 28559.46 | 2350.50 | 8.2%
2007-04-07 | 4 | 1984.28 | 28559.46 | 4334.78 | 15.2%
2007-04-08 | 4 | 2227.84 | 28559.46 | 6562.62 | 23.0%
2007-04-09 | 4 | 2067.86 | 28559.46 | 8630.48 | 30.2%
2007-04-10 | 4 | 1973.18 | 28559.46 | 10603.66 | 37.1%
2007-04-11 | 4 | 1940.32 | 28559.46 | 12543.98 | 43.9%
2007-04-12 | 4 | 1930.48 | 28559.46 | 14474.46 | 50.7%
2007-04-26 | 4 | 347.21 | 28559.46 | 14821.67 | 51.9%
2007-04-27 | 4 | 2673.57 | 28559.46 | 17495.24 | 61.3%
2007-04-28 | 4 | 2622.73 | 28559.46 | 20117.97 | 70.4%
2007-04-29 | 4 | 2717.60 | 28559.46 | 22835.57 | 80.0%
2007-04-30 | 4 | 5723.89 | 28559.46 | 28559.46 | 100.0%
2007-05-14 | 5 | 514.18 | 514.18 | 514.18 | 100.0%
(32 rows)