Most useful data lives across more than one table — customers in one table, their orders in another. An INNER JOIN is how you combine rows from two tables based on a related column, returning only the rows where a match exists in both tables. It's the single most important SQL concept to understand once you move past single-table queries.

Throughout this course, joins are demonstrated with two tables: a customers table (id, name, city) and an orders table (id, customer_id, amount, order_date), where orders.customer_id is a foreign key referencing customers.id.

Basic INNER JOIN Syntax

SELECT customers.name, orders.amount, orders.order_date
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;

Result:

name | amount | order_date
------------+--------+-----------
Ravi Kumar | 120.00 | 2026-01-10
Ravi Kumar | 45.00 | 2026-01-22
Meera Nair | 300.00 | 2026-01-15

Notice only customers who have placed at least one order show up — that's the defining trait of an INNER JOIN. If a customer exists with zero orders, they're simply left out of the result entirely (that's what LEFT JOIN is for, if you need them included anyway).

Using Table Aliases

Real queries get verbose fast, so it's standard practice to alias table names to keep things readable:

SELECT c.name, o.amount, o.order_date
FROM customers AS c
INNER JOIN orders AS o ON c.id = o.customer_id
WHERE o.amount > 100;

Result:

name | amount | order_date
------------+--------+-----------
Ravi Kumar | 120.00 | 2026-01-10
Meera Nair | 300.00 | 2026-01-15

The AS keyword is actually optional — customers c works identically to customers AS c — but writing it out explicitly makes the query easier to read at a glance.

The Old Comma-Join Style (Avoid This)

You may encounter older code that joins tables using a comma in the FROM clause and puts the join condition in WHERE instead:

-- Works, but considered outdated style
SELECT c.name, o.amount
FROM customers c, orders o
WHERE c.id = o.customer_id;

This produces identical results to the explicit INNER JOIN ... ON syntax above, but it's easy to forget the WHERE condition and accidentally produce a cartesian product (every row from one table matched with every row from the other). The explicit JOIN syntax makes the intent — and the join condition — impossible to miss, which is why it's the standard today.

Once INNER JOIN feels natural, the next concept worth understanding is GROUP BY, which is often combined with a join to summarize data — for example, the total amount each customer has spent.