Python Central HubSign in

Data Analytics with Python / Phase 9: SQL for Data Analytics

Window Functions (OVER, PARTITION BY)

Compute running totals, rankings, and cohort-like metrics without collapsing rows.

Why window functions

Window functions let you compute metrics across related rows while keeping each row.

Common uses:

  • Rank customers by revenue
  • Running totals over time
  • Moving averages

ROW_NUMBER and RANK

SQL
SELECT
  user_id,
  order_id,
  amount,
  ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rn
FROM orders;

Running total

SQL
SELECT
  order_date,
  daily_revenue,
  SUM(daily_revenue) OVER (ORDER BY order_date) AS running_revenue
FROM (
  SELECT
    DATE(order_ts) AS order_date,
    SUM(amount) AS daily_revenue
  FROM orders
  GROUP BY DATE(order_ts)
) t
ORDER BY order_date;

PARTITION BY

  • Splits data into groups
  • Window function works within each group

Example: running revenue by country.

Window functions vs GROUP BY

The key difference from GROUP BY: a window function does not collapse rows. Every input row stays in the result, but each row also gets a computed value based on the rows around it (its "window").

diagram How OVER (PARTITION BY ...) works mermaid
PARTITION BY splits rows into windows; the function computes a value per row using only the rows in its own window.
sketch Partitions computed independently p5.js
Rows are grouped into colored partitions; RANK restarts at 1 inside each partition instead of continuing across the whole table.

Check your understanding

quizCheck yourself
  1. What is the key difference between a window function and GROUP BY?

    Show answer

    A — A window function keeps every input row — GROUP BY collapses rows, while a window function adds a computed value to each row.

  2. What does ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) return?

    Show answer

    A — A rank of each order within its user, 1 for the largest amount — PARTITION BY restarts the numbering for each user, and ordering by amount descending gives the largest order rn = 1.

  3. What happens if you forget PARTITION BY in a per-user running total?

    Show answer

    A — It quietly becomes a global total across the table — Without PARTITION BY the whole table is one window.

  4. How is the running revenue computed in the lesson?

    Show answer

    A — SUM(daily_revenue) OVER (ORDER BY order_date) — A SUM window ordered by date accumulates daily revenue from the first date to the current row.

🧪 Try It Yourself

Exercise 1 – ROW_NUMBER per partition

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 2 – Running total with SUM() OVER

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 3 – RANK vs ROW_NUMBER on ties

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Next

CTEs (WITH) and Subqueries show you how to name and reuse the derived tables you've been building inline with subqueries so far.

Was this page helpful?

Let us know how we did