Inner Joins
The most common join — keeping only the rows that have a match in both tables — with clear visuals of what stays and what disappears.
The join you met on the previous page was an inner join, the default and most common kind. Its rule is simple and worth saying precisely: an inner join keeps only the rows that have a match in both tables. Rows with no partner are dropped.
The rule, in a picture
If an order points to a customer who exists → it appears. If a customer has no orders → they do not appear. Only the overlap survives.
Seeing what survives and what drops
This data is rigged to show the rule. There is an order with no matching customer, and a customer with no orders. Watch both vanish from an inner join:
The result shows Ada (two orders) and Grace (one). Linus is absent (no orders to match), and order 104 is absent (its customer 7 does not exist). That is the inner join doing its job: no match, no row.
INNER is optional
JOIN and INNER JOIN mean exactly the same thing — INNER is the
default, so people usually just write JOIN. Writing it out can
make your intent explicit when a query also contains outer joins.
When an inner join is the right choice
Use an inner join when you only care about rows that are connected — which is most of the time:
- "Orders with their customer details" — you do not want customer-less orders.
- "Students and the courses they are enrolled in" — empty enrollments are irrelevant.
- "Products that have been sold" — unsold products are not part of the question.
The giveaway is the word with or that have: you want rows that do have a counterpart.
Joining more than two tables
Real questions often span three tables. You chain joins, each with
its own ON. Here orders connect to both customers and products:
Each JOIN ... ON ... adds one more connected table. The pattern
scales: the orders table sits in the middle, linking customers to
the products they bought. This is everyday relational querying.
Check your understanding
What rows does an inner join include in its result?
Every row from both tables, matched or not.
Only rows that have a matching row in both tables.
Only rows from the left table.
Only rows where both tables are empty.
A customer named Linus has no orders. In an INNER JOIN between customers and orders, does Linus appear?
Yes, with all his order columns shown.
No — with no matching order, an inner join drops him entirely.
Yes, but only if the orders table is empty.
It causes an error.
You want "all products that have actually been sold." Which join expresses this best?
An outer join that keeps unsold products too.
An inner join between products and orders, keeping only products with a matching order.
No join at all; just select from products.
A join with no ON condition.
Practice challenge
Join orders to customers. Return one row per order with the customer's name, their city, and the order amount, sorted from the largest amount to the smallest.