Lessons · SQL · when a join multiplies rows
When a join multiplies rows
Joining one order to its three items gives three rows, each carrying the order's amount. Summing that column afterwards counts the order three times.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
Revenue that doubles after a join, a total that disagrees with finance: fan-out is the usual cause, and the query runs without a single error.
How to think about it
Before summing after a join, ask what one row means now. Aggregate the many side first in a CTE, then join one row per key; and compare the row count before and after the join.
Worked example
SELECT o.id, o.amount, r.stars FROM orders o JOIN reviews r ON r.customer_id = o.customer_id;One row per order-review pair: an order with three reviews now appears three times.
WITH per_customer AS (SELECT customer_id, COUNT(*) AS reviews FROM reviews GROUP BY customer_id) SELECT o.id, o.amount, p.reviews FROM orders o JOIN per_customer p ON p.customer_id = o.customer_id;Aggregate the many side first: one row per customer, so each order stays one row.
Your turn
Check the join kept one row per order.
SELECT COUNT(*) FROM orders o JOIN per_customer p ON p.customer_id = o.customer_id; -- compare with SELECT COUNT(*) FROM ;
Run a query against real tables
The trap
A key that repeats on both sides multiplies: three rows each side make nine. Deduplicate the lookup side before joining.