SQL for Analytics II — Joins & Windows
P12.data-quality-sql.02 · Audience: guest, it-ml, language-pro · Prerequisites: SQL for Analytics I — Select, Filter, Group
Last module left one black box: the JOIN that lined each order up with its price and its city. Joins are where SQL earns its keep — almost every real question spans more than one table — and also where it does its quietest damage. A join that matches one extra row does not error, does not warn; it just returns a number that is too big, and that number can ride all the way into a report before anyone notices. This module opens the box: how joins match rows, the inner-vs-left choice, the silent row-multiplication that a single duplicated dimension row causes, and then window functions — running totals and latest-per-key dedup, computed without collapsing the rows away.
A join pairs each row of one table with the rows of another that match on a key. To price an order we pair its product_id with the products row carrying the same id; to place it in a city we pair its customer_id with the matching customers row. The engine walks the orders and, for each, finds the matching dimension row and glues the columns together into one wider row.
SELECT o.order_id, o.quantity, p.price
FROM orders o
JOIN products p ON o.product_id = p.product_id;Three orders, each matching exactly one product, gives three joined rows — o1+10.0, o2+20.0, o3+10.0. The ON clause is the matching rule; USING (product_id) is shorthand when the key column has the same name on both sides.
ⓘ Concept: A join is a matched pairing, not a concatenation
Why it matters — The mental model that keeps you out of trouble: for every row on the left, the engine looks up all matching rows on the right and emits one output row per match. 'One match' is the case you picture — but the machinery is 'all matches', and the number of output rows is the sum of match-counts, not the row count of either table. Hold that and the row-multiplication bug later in this module stops being a surprise and becomes an obvious consequence.
Ask the mentor about this module
Ask a question about this content. The mentor explains and grounds its answer in what you are studying; asking is recorded as a learning signal, not a grade.
🎓 Practice ladder
4 graded rungs · ~37 minNow run the joins yourself. Each rung is a three-panel workspace: instructions on the left, a code editor in the middle, output and test results on the right. Run checks the visible tests; Submit grades against hidden edge cases. The explorer rung has you predict which join produced how many rows; the practitioner rungs defuse the silent multiplier and build a running total; the senior rung writes the latest-record dedup, tie included.
Rung 1 — Predict the join (explorer)
Loading exercise…
Rung 2 — The silent multiplier
Loading exercise…
Rung 3 — Running totals
Loading exercise…
Rung 4 — Latest-record dedup (senior)
Loading exercise…
Try it yourself
A scratch console for this page's ideas — ungraded, nothing you run here is recorded.
Scratch console
A scratch console with the scientific stack (pandas, numpy, scikit-learn). Runs on the server — no network, resource-limited and measured.
Output appears here.
Where next?
Later in Data Quality & SQL
Go up a level