BA Prince the B.A. Subscribe

Home / SQL for Business Analysts

Why Your SQL Join Returns Too Many Rows (One-to-Many Fan-Out)

Why Your SQL Join Returns Too Many Rows (One-to-Many Fan-Out)

Watch on YouTube Subscribe

Joining orders to order items repeats each order once per product, so a SUM of the order total comes out almost three times too big. See the fan-out row by row, then add up the values from the right table.

Step by step

Too many rows

  1. A total that's too big. You add a join, and suddenly your sales total is almost three times bigger. Nothing crashed, so nobody notices. Let's see why it happens, and how to fix it.
  2. The true total. First, the true answer. The sum of the order total, from orders. Fifteen thousand, three hundred and twenty two. Remember that number.
    SELECT SUM(order_total) AS sales
    FROM orders;

Add a join

  1. Add a join. Now someone joins order items, maybe to filter by product later. Same sum, but from orders joined to order items on the order ID. Forty thousand, three hundred and eleven. Same question, a much bigger answer. No error, just a wrong number.
    FROM orders AS o
    JOIN order_items AS i
      ON i.order_id = o.order_id;
  2. Wrong total. This is the number that ends up in a report if nobody checks it.

Find the fan-out

  1. Look at one order. Let's look at a single order, ten oh four. Show its ID, its total, and the product ID from order items. Three rows for one order. It has three products, so the join repeats the order once for each product.
    SELECT o.order_id, o.order_total, i.product_id
    FROM orders AS o
    JOIN order_items AS i
      ON i.order_id = o.order_id
    WHERE o.order_id = 1004;
  2. The same total, three times. And here's the problem. The same total, four hundred and fifty two, three times. Sum adds all three. That's called a fan-out.

The fix

  1. Sum the many side. The fix is to add up values from the many side. Each item row has a quantity and a unit price. Quantity times price, summed, gives the sales. Fifteen thousand, three hundred and twenty two. The true total is back, even with the join.
    SELECT SUM(i.quantity * i.unit_price) AS sales
    FROM orders AS o
    JOIN order_items AS i
      ON i.order_id = o.order_id;

Recap

  1. The fan-out rule. So, when one row matches many, a join repeats it, and sums get too big. Check the row count after a join, and add up values from the many side.

More in SQL for Business Analysts