MySQL Inner Join
INNER JOIN returns only the rows where the joined tables have a matching value, discarding anything without a partner on both sides.
How INNER JOIN Filters Rows
INNER JOIN compares rows from two tables using the condition in the ON clause and keeps only the pairs where that condition is true. If a customer has never placed an order, INNER JOIN simply omits that customer from the result, because there's no order row to pair it with. This makes INNER JOIN the right choice whenever you only care about complete, matched relationships, such as 'orders together with the customer who placed them'.
Orders with customer names
SELECT o.order_id, c.name, o.total_amount
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id;Multiple Matches Multiply Rows
When the relationship is one-to-many, an INNER JOIN produces one output row for every matching pair, not one row per record on the 'one' side. Joining orders to order_items, where a single order can contain five line items, returns five rows for that order - each repeating the order's details alongside a different item. This is expected: a join operates on pairs of matching rows, not on parent records.
Every line item alongside its order
SELECT o.order_id, o.order_date, oi.product_id, oi.quantity
FROM orders o
INNER JOIN order_items oi ON oi.order_id = o.order_id;Adding Extra Conditions
Extra filters can go in the ON clause or the WHERE clause with an INNER JOIN and, unlike with LEFT or RIGHT JOIN, the result is identical either way, since unmatched rows were never going to appear regardless. Most developers put join logic - how tables relate - in ON, and business filters - which rows to keep - in WHERE, purely for readability.
Only orders over 5000 from Delhi customers
SELECT o.order_id, c.name, o.total_amount
FROM orders o
INNER JOIN customers c ON o.customer_id = c.customer_id
WHERE c.city = 'Delhi' AND o.total_amount > 5000;- Writing plain JOIN is identical to writing INNER JOIN - INNER is the default and entirely optional.
- Any number of INNER JOINs can be chained in a single query to pull in more related tables.
- The order tables are listed in an INNER JOIN doesn't change the result, only readability.
- An INNER JOIN with no ON clause, or a condition that's always true, produces a cross join - every row of one table paired with every row of the other.