Advanced Case 37 of 50

Case 037: Month-over-Month

orderspayments

Leadership already has the monthly revenue numbers from before — but a single month's total on its own doesn't say whether the business is actually heading up or down.

The manager wants that comparison built in: "Revenue by month is good, but I want to see the change — are we growing or shrinking, month to month?"

The data Alex is looking at

orders
idcustomer_idorder_date
10112026-01-05
10222026-01-08
10332026-01-12
10412026-01-20
10542026-02-01
… 23 more rows
payments
idorder_idamount
6011016200
6021023500
6031033600
60410460000
60510512000
… 23 more rows
TASK

Help Alex answer the manager:

“Show total revenue per month, along with the change from the previous month.”
SQL editor Ctrl+Enter to run
Write a query above and hit Run to see what comes back.
No hints requested yet — click "Get a hint" when you're stuck.
Alex's final query — this is for reference. Copy it into your own thinking, not into the editor above.
WITH monthly AS ( SELECT DATE_FORMAT(orders.order_date, '%Y-%m') AS month, SUM(payments.amount) AS revenue FROM orders JOIN payments ON payments.order_id = orders.id GROUP BY month ) SELECT month, revenue, revenue - LAG(revenue) OVER (ORDER BY month) AS change_from_prev_month FROM monthly ORDER BY month;
What that query returns
Case Debrief LAG over an aggregated CTE (time-series comparison)
  • Window functions work just as well over an aggregated CTE as over raw rows — this is the standard pattern for any "compared to last period" report.

Case closed.

Ready for the next one?

Next: Case 038 — Best Seller Per Category →