INNER JOIN
Real data is rarely stored in a single table. Customer information lives in one table, their orders in another, the products they ordered in a third. JOINs are how you bring related rows from multiple tables back together in a single query — and INNER JOIN is the most common and fundamental of them.
What INNER JOIN does
Example tables
Consider two small tables:
id | name |
|---|---|
1 | Alice |
2 | Bob |
3 | Carla |
customers above, and orders below:id | customer_id | amount |
|---|---|---|
101 | 1 | 250 |
102 | 1 | 75 |
103 | 2 | 40 |
customer_id of 3.Writing the join
INNER JOIN with an ON clause
SELECT customers.name, orders.id AS order_id, orders.amount FROM customers INNER JOIN orders ON customers.id = orders.customer_id;
The ON clause tells the database how to match rows across the two tables — here, wherever a customer’s id equals an order’s customer_id. The result:
name | order_id | amount -------+----------+-------- Alice | 101 | 250 Alice | 102 | 75 Bob | 103 | 40
orders.JOIN without a qualifier defaults to INNER JOIN — they are exactly equivalent. Many developers write plain JOIN for this most common case and reserve explicit qualifiers like LEFT JOIN for joins that need one.These two queries are identical
SELECT * FROM customers JOIN orders ON customers.id = orders.customer_id; SELECT * FROM customers INNER JOIN orders ON customers.id = orders.customer_id;
Table aliases keep it readable
Once you’re joining multiple tables, repeating full table names gets noisy. Aliases shorten them:
Using aliases
SELECT c.name, o.id AS order_id, o.amount FROM customers AS c INNER JOIN orders AS o ON c.id = o.customer_id;
Joining on more than one condition
The ON clause can combine multiple conditions with AND, useful when a match depends on more than one column:
Multi-column join condition
SELECT * FROM order_items oi INNER JOIN price_history ph ON oi.product_id = ph.product_id AND oi.order_date BETWEEN ph.valid_from AND ph.valid_to;
INNER JOIN keeps only rows with a match on both sides of the join
Rows with no match in the other table (like Carla, above) are dropped entirely
Plain JOIN and INNER JOIN are the same thing
If you need unmatched rows preserved, you'll want LEFT JOIN or FULL OUTER JOIN, covered next