Atterna
RUEN
Get access

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.idamountitems in the order
1€503
2€301
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. 1

    Count rows before and after every join.

  2. 2

    If the count grew, sum only columns that belong to the many side.

  3. 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

An AI assistant

“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.”
Paste a real AI answer into the checker — it writes these questions for you →

Read next

Examples use Meridian, Atterna’s fictional practice marketplace.