pbPassingBI
/
Combining data intermediate 6 min

Joining three or more tables

Chaining joins, keeping them readable, and where the row count goes wrong.

What you'll be able to do
  • Join several tables in one query
  • Keep multi-table joins readable
  • Locate which join caused a fan-out

Chaining joins

SELECT c.name, p.product_name, li.quantity, o.order_date
FROM orders o
JOIN customers  c  ON c.customer_id = o.customer_id
JOIN line_items li ON li.order_id    = o.order_id
JOIN products   p  ON p.product_id  = li.product_id
WHERE o.order_date >= '2024-01-01';

Joins are applied in order, each working on the accumulated result. Start from the table whose grain you want the output to have — here, one row per line item.

Mixing inner and outer

Order matters when you mix them. An INNER JOIN placed after a LEFT JOIN can eliminate the rows the LEFT JOIN was preserving, because the inner join demands a match.

If you need to preserve rows through a chain, the later joins usually need to be LEFT as well.

Finding a fan-out

In a four-table join returning too many rows, add the joins back one at a time and count after each:

SELECT COUNT(*) FROM orders;                       -- 1,000
-- + customers                                     -- 1,000  fine
-- + line_items                                    -- 3,400  expected fan-out
-- + products                                      -- 6,800  wrong, investigate

The jump tells you which join has duplicate keys on the side you assumed was unique.

Readability

Consistent aliases, one join per line, and the ON condition written with the joined table on the left all help. On anything beyond four tables, a CTE per logical step is usually easier to follow and to debug than one long FROM clause.

Key points
  • Joins apply in order; each works on the accumulated result
  • An INNER JOIN after a LEFT JOIN can undo the outer join
  • Add joins one at a time and count rows to locate a fan-out
Check yourself