SQL module
Lesson 11
Window analytics
Running totals, LAG/LEAD, and moving comparisons for time-aware retail metrics.
beginner40 minRun on your machine
What you will be able to do
- Compute a running sum with SUM() OVER
- Use LAG to compare to the previous period
- Build a simple day-over-day change
Why this matters for data work
Trends need previous row context: yesterday’s revenue, prior order for a customer, cumulative spend. LAG/LEAD and running SUM are the toolkit.
Concepts
SUM(x) OVER (PARTITION BY … ORDER BY … ROWS UNBOUNDED PRECEDING)LAG(col, 1) OVER (ORDER BY …)— previous row value.- Frame clauses matter for running aggregates; default varies by function — be explicit when unsure.
Practice on your machine
export PGPASSWORD=dcubes PGHOST=127.0.0.1 PGPORT=15432 PGUSER=dcubes PGDATABASE=retail
psql << 'SQL'
WITH daily AS (
SELECT order_ts::date AS d, round(sum(line_total), 2) AS revenue
FROM orders
WHERE status = 'completed'
GROUP BY 1
)
SELECT
d,
revenue,
lag(revenue) OVER (ORDER BY d) AS prev_day,
round(revenue - lag(revenue) OVER (ORDER BY d), 2) AS dod_change,
round(sum(revenue) OVER (ORDER BY d ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 2) AS cumulative
FROM daily
ORDER BY d DESC
LIMIT 14;
SQL
What you should see
- One row per day with revenue.
prev_dayanddod_change(first day NULL prev).- Growing
cumulativewhen ordered ascending (check full sort).
Common mistakes
- LAG without ORDER BY — meaningless.
- Comparing unsorted timestamps.
- Running sum frame wrong — totals jump unexpectedly.