Join fan-out
Also called: row multiplication
When a join to a one-to-many table repeats each row once per match, so aggregates of the “one” side are counted several times.
Formularows after join = Σ matches per row, not one per row
Try it · 30 seconds · from Atterna’s practice
| orders.id | amount | items in the order |
|---|---|---|
| 1 | €50 | 3 |
| 2 | €30 | 1 |
SELECT SUM(o.amount) FROM orders o JOIN items i ON i.order_id = o.id;
What does this query return?
Preparing the practice…
How we work it through
- 1
Count rows before and after every join.
- 2
If the count grew, sum only columns that belong to the many side.
- 3
Or aggregate the many side first, then join one row per key.
On the practice dataset
The query we run on Meridian, Atterna’s practice marketplace, and what it returns.
SELECT COUNT(*), SUM(o.items_total_eur)
FROM meridian.orders o
JOIN meridian.order_items i ON i.order_id = o.order_id
WHERE o.status = 'paid';Result16,192 rows and €1,239,938 — 2.2× the real GMV of €552,645
The common trap
SUM after the join: no error, just a total that is too high.
ExampleMeridian: 9,071 paid orders become 16,192 rows after joining order items; summed GMV rises from €552,645 to €1,239,938.
When an AI answers
“Total revenue from paid orders is €1,239,938.”
- What it didn’t know
- It joined order items to add product names and did not notice each order now repeats.
- Ask back
- “Did the join repeat orders? Show the row count before and after it.”
Read next
Examples use Meridian, Atterna’s fictional practice marketplace.