Lessons › SQL › Go further in SQL: Business questions
SQL lesson
What was each store's month-on-month growth?
What was each store's month-on-month growth, as a decimal? Growth is this month minus last month, divided by last month. That needs each store's monthly totals first, then last month's total on the same row (LAG), then the safe division from Chapter 8.
Try this lesson free →Example
This month against last, as a share of last
WITH m AS (
SELECT store,
TO_CHAR(order_date, 'YYYY-MM') AS month,
SUM(revenue) AS revenue
FROM orders
GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')
)
SELECT store,
month,
1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month))
/ NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth
FROM m| store | month | growth |
|---|---|---|
| Abuja | 2026-02 | |
| Abuja | 2026-03 | 2.714 |
| Accra | 2026-02 | |
| Accra | 2026-03 | -0.754 |
| Lagos | 2026-02 | |
| Lagos | 2026-03 | 1.181 |
Step by step
- February has no month before it, so its growth is empty.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m - The month comes from order_date with TO_CHAR.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m - Every order counts.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m - A CTE for the totals, then LAG(revenue) OVER (PARTITION BY store ORDER BY month).
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m
Practice
1. What was each store's month-on-month growth? Show store, month and growth as a decimal.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m2. What was each store's month-on-month change in orders, as a decimal? Show store, month and order_growth.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, COUNT(*) AS orders FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')) SELECT store, month, 1.0 * (orders - LAG(orders) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(orders) OVER (PARTITION BY store ORDER BY month), 0) AS order_growth FROM m3. What was each product's month-on-month revenue growth, as a decimal? Show product, month and growth.
WITH m AS (SELECT product, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY product, TO_CHAR(order_date, 'YYYY-MM')) SELECT product, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY product ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY product ORDER BY month), 0) AS growth FROM m4. What was total revenue's month-on-month growth across all stores? Show month and growth.
WITH m AS (SELECT TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY TO_CHAR(order_date, 'YYYY-MM')) SELECT month, 1.0 * (revenue - LAG(revenue) OVER (ORDER BY month)) / NULLIF(LAG(revenue) OVER (ORDER BY month), 0) AS growth FROM m5. Which stores grew from February to March? Show store and growth.
WITH m AS (SELECT store, TO_CHAR(order_date, 'YYYY-MM') AS month, SUM(revenue) AS revenue FROM orders GROUP BY store, TO_CHAR(order_date, 'YYYY-MM')), g AS (SELECT store, month, 1.0 * (revenue - LAG(revenue) OVER (PARTITION BY store ORDER BY month)) / NULLIF(LAG(revenue) OVER (PARTITION BY store ORDER BY month), 0) AS growth FROM m) SELECT store, growth FROM g WHERE growth > 0Learn it by doing. This lesson is a short hands-on level on Bampaa: see it work, then build and write it yourself, with instant feedback.
Try this lesson free →