All posts
6 min read · 2026-04-21

Reading a SQL JOIN: a visual walkthrough

joins
fundamentals

Most join tutorials use Venn diagrams, which is unhelpful because joins do not actually intersect sets. Joins build pairs of rows. Here is the model that fits real SQL.

INNER JOIN

Pair every row on the left with every row on the right that matches the ON condition. Drop unmatched rows on both sides.

LEFT JOIN

Pair every left row with matching right rows. If no right row matches, keep the left row and fill the right side with NULLs.

FULL OUTER JOIN

LEFT JOIN + RIGHT JOIN, deduped. Useful for reconciling two systems that should agree but don't.

CROSS JOIN

Every left row with every right row. Almost always a bug, sometimes a feature (think: calendar × accounts).

How lineage helps

When you visualize the lineage of a query with multiple joins, each join becomes an edge feeding into the projected columns. If you see two edges from one parent table feeding the same column, you have a fan-out. If you see no edge, you have a missed reference. The graph is the picture you have been missing.

usersordersproductsuser_order_products
A two-join SELECT as lineage: each parent table contributes edges into the final projected columns.

Try it on your own SQL: