lesson 38 Window functions · intermediate
Logical query processing & row grain
Follow query processing and track what one row represents.
the idea
Think FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. This is a logical model, not a promise about physical execution. Row expressions preserve rows, aggregates collapse them, and windows add context without collapsing.
tables in this lesson
The challenges use this data. Each column shows its type underneath; → marks a link to another table.
orders6 columns · 12 rows
| idinteger · key | customer_idinteger | product_idinteger | quantityinteger | statustext | ordered_attext |
|---|---|---|---|---|---|
| 101 | 1 | 1 | 2 | paid | 2025-01-01 |
| 102 | 2 | 3 | 1 | paid | 2025-01-02 |
| 103 | 1 | 2 | 1 | paid | 2025-01-05 |
| 104 | 3 | 5 | 2 | pending | 2025-01-08 |
| 105 | 4 | 4 | 5 | paid | 2025-02-01 |
showing 5 of 12 rows
example
The idea in one query. Press Run to see what it returns; running examples never affects your progress.
SELECT customer_id,SUM(quantity) AS units FROM orders WHERE status='paid' GROUP BY customer_id HAVING SUM(quantity)>2 ORDER BY units DESC;
Watch for: SQLite accepts some alias usages other engines reject. Prefer clear expressions or an outer query for portable SQL.
build it step by step
Each step changes one thing. Run them in order and watch the result change.
Start with rows. One row is one paid order line.
step-1.sqlSELECT id,customer_id,quantity FROM orders WHERE status='paid';
Aggregate. Customers become the output grain.
step-2.sqlSELECT customer_id,SUM(quantity) AS units FROM orders WHERE status='paid' GROUP BY customer_id;
Filter groups. HAVING works on the totals, then ordering shapes the output.
step-3.sqlSELECT customer_id,SUM(quantity) AS units FROM orders WHERE status='paid' GROUP BY customer_id HAVING SUM(quantity)>2 ORDER BY units DESC,customer_id
Keep individual rows instead. A window attaches the customer total while retaining order rows.
step-4.sqlSELECT id, customer_id, quantity, SUM(quantity) OVER(PARTITION BY customer_id) AS customer_units FROM orders WHERE status='paid'