INNER JOIN

Return only the rows that match in both tables — and know when a non-unique key silently duplicates them.

Edit this pageReport an issue

Syntax

SELECT ...
FROM left_table lt
INNER JOIN right_table rt
  ON lt.key = rt.key;

INNER JOIN and plain JOIN are the same thing — the INNER is optional.

What it does

Keeps only the rows with matching keys in both tables. It's the default join when you're filtering to relationships that actually exist.

Example

SQL playground
Loading editor…
⌘/Ctrl + Enter

Customers 6 and 7 (Wayne Enterprises, Soylent) have no orders — they simply don't appear. That's INNER JOIN's defining behavior; if you need them anyway, that's a LEFT JOIN.

Fan-out: the row count can grow

If the right table has more than one matching row per key, the left row repeats — once per match:

SQL playground
Loading editor…
⌘/Ctrl + Enter

Customer 1 has 3 orders, so joining customers to orders on customer_id turns that one customer row into three. This is correct when you want one row per order — but if you then SUM() a customer-level column without grouping, you'll silently multiply it. Always check the row count against what you expect before trusting a join's aggregate.

Hit this as an actual error?

Safety check before shipping

  • confirm the join key represents the intended relationship
  • inspect row counts before and after the join
  • decide whether duplicates (fan-out) are valid or indicate a broken relationship
Was this page helpful?

On this page