Intermediate

JOINs

Learn to combine data from multiple tables using INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN, and self-joins.

Why JOINs Matter

Real-world data is spread across multiple tables. JOINs let you combine related data by matching rows based on common columns (keys). This is the foundation of relational database design.

INNER JOIN

Returns only rows that have matching values in both tables.

SQL
SELECT o.id, u.name, o.total, o.order_date
FROM orders o
INNER JOIN users u ON o.user_id = u.id;

-- Only returns orders where the user exists,
-- and users who have placed orders.

LEFT JOIN (LEFT OUTER JOIN)

Returns all rows from the left table and matching rows from the right. Unmatched right-side rows appear as NULL.

SQL
-- All users, even those without orders
SELECT u.name, o.id AS order_id, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- Find users who have never ordered
SELECT u.name
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
Data science tip: LEFT JOIN + IS NULL is a common pattern to find missing relationships — customers without purchases, products without reviews, users without logins.

RIGHT JOIN and FULL OUTER JOIN

SQL
-- RIGHT JOIN: all orders, even if user was deleted
SELECT u.name, o.id, o.total
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;

-- FULL OUTER JOIN: all rows from both tables
SELECT u.name, o.id, o.total
FROM users u
FULL OUTER JOIN orders o ON u.id = o.user_id;

JOIN Types Summary

JOIN TypeLeft TableRight TableUse Case
INNERMatching onlyMatching onlyGet related data from both tables
LEFTAll rowsMatching onlyKeep all left rows, add right data
RIGHTMatching onlyAll rowsKeep all right rows, add left data
FULL OUTERAll rowsAll rowsSee everything, find mismatches
CROSSAll rowsAll rowsCartesian product (every combination)

Multi-Table JOINs

SQL
-- Join three tables: orders + users + products
SELECT u.name,
       p.product_name,
       oi.quantity,
       oi.quantity * p.price AS line_total
FROM order_items oi
INNER JOIN orders o ON oi.order_id = o.id
INNER JOIN users u ON o.user_id = u.id
INNER JOIN products p ON oi.product_id = p.id
ORDER BY u.name, p.product_name;

Self-Joins

A table joined to itself. Useful for hierarchical data or comparing rows within the same table.

SQL
-- Find employees and their managers
SELECT e.name AS employee,
       m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
Watch for duplicates. JOINs can multiply rows if there are multiple matches. Always check row counts before and after a JOIN to ensure you get the expected results.