INNER JOIN

Combine rows from two tables where a condition matches

Intermediate 16 minJOININNER JOIN

Joining Tables Together

INNER JOIN combines rows from two tables where a join condition matches. Databases split data across tables to avoid repetition — INNER JOIN is how you reassemble it. Here's how it works:

The ON clause defines the link — Typically matches a foreign key to a primary key: ON orders.customer_id = customers.id. This tells the database which rows from each table belong together in the combined result.
Both sides must match — Rows without a match in either table are silently excluded. Customer with no orders? Not in the result. Order with a bad customer_id? Also excluded. Only matching pairs survive.
Use table aliases — Short names like c for customers and o for orders keep multi-table queries clean and readable. Aliases become required when both tables share a column name: c.id vs o.id.
Knowledge Canvas

Core Mechanics / How It Works

Combine rows from two or more tables

AB
  • Matches rows where the ON condition is TRUE
  • No match on either side → row excluded from result
  • JOIN without INNER keyword = still INNER JOIN
  • Always use table aliases when joining

Warnings & Gotchas

Common mistakes and errors to watch out for

  • Unexpected duplicate rows from one-to-many relationships
  • Accidental cross joins without ON clause
  • NULL handling issues — NULLs never match in ON conditions
  • Unequal matching columns produce wrong or inflated results

Power Patterns & Performance Tips

Optimize your joins for faster queries

  • Index the join columns on both tables
  • Use EXPLAIN plans to learn query intent
  • Prefer INNER JOINs over OUTER when possible
  • Join smaller datasets first to reduce intermediate size
EXPLAINOPTIMIZER

Critical Rules to Remember

Know your join behavior by heart

  • Specify join types explicitly — don't rely on defaults
  • Always use an ON clause — never accidental cartesian products
  • NULL never equals NULL in join conditions
  • Join on indexed columns for best performance

Relations & Connections

How join types relate to each other

AB
  • INNER JOIN = intersection of both tables
  • LEFT JOIN = all left + matched right
  • RIGHT JOIN = all right + matched left
  • FULL OUTER JOIN = everything from both sides

Join Type Comparison

When to use which join

INNER: only matches survive
LEFT: all left rows survive
CROSS: every combination (cartesian)
SELF: table joined to itself
Use INNER for linked data
Use LEFT for "find what's missing"
Syntax
Syntax Template
1SELECT
2 a.col,
3 b.col
4FROM table_a a
5INNER JOIN table_b b
6 ON a.key = b.key;
INNER JOINOnly returns rows with matches in BOTH tables
ONThe condition that links the two tables
Aliases (a, b)Short names for tables — required when column names overlap
Sample Data
orders
12 rows
idcustomer_idtotal
5001C100159.98
5002C1002449
5003C100112.5
5004C100389.99
5005C1006245
5006C1005159
5007C100445.5
5008C100979
5009C1012425
5010C100718.99
5011C1008134
5012C101065.5
customers
12 rows
idnamecity
C1001Aarav SharmaMumbai
C1002Sara ChenSingapore
C1003James WilsonLondon
C1004Maria GarciaMadrid
C1005Yuki TanakaTokyo
C1006Priya PatelDelhi
C1007Alex JohnsonNew York
C1008Chen WeiShanghai
C1009Emma BrownSydney
C1010Omar HassanDubai
C1011Lena MullerBerlin
C1012Ravi KumarBangalore
products
10 rows
idnamecategorypricestock
P101Wireless MouseElectronics24.99150
P102Office DeskFurniture18925
P103LED Desk LampFurniture45.580
P104USB-C CableElectronics12.99500
P105Bluetooth SpeakerElectronics7960
P106Office ChairFurniture9515
P107Coffee MakerAppliances89.9940
P108Notebook SetStationery8.5200
P109Wireless HeadphonesElectronics15930
P110Standing DeskFurniture4258
reviews
12 rows
idproduct_idcustomer_idratingcomment
7001P101C10015Excellent mouse, very comfy
7002P101C10034NULL
7003P101C10053Good but battery drains fast
7004P102C10025Solid build, worth every rupee
7005P102C10064Spacious — fits two monitors
7006P103C10044NULL
7007P104C10075Just works, durable braided cable
7008P105C10095Great sound for the price
7009P105C10124Battery could be better
7010P107C10083NULL
7011P108C10115Good notebooks, smooth paper
7012P109C10015Premium feel, noise cancellation is real

Worked Example

Show each order with the customer name and city.

SQL
1SELECT
2 o.id AS order_id,
3 c.name AS customer,
4 c.city,
5 o.total
6FROM orders o
7INNER JOIN customers c
8 ON o.customer_id = c.id
9ORDER BY
10 o.id;
For each order, the database finds the customer row where customers.id matches orders.customer_id. The result combines columns from both tables into a single row. Aliases o and c keep the query short.
Output
4 rows
order_idcustomercitytotal
5001Aarav SharmaMumbai59.98
5002Sara ChenSingapore449
5003Aarav SharmaMumbai12.5
5004James WilsonLondon89.99

Key Concepts

1INNER JOIN = only rows with matches in BOTH tables survive
2No match on either side → row silently excluded
3Writing JOIN without INNER is the same — INNER is the default
4Always use table aliases when joining to keep queries readable

Pro Tip

Real data lives in separate tables. INNER JOIN is how you reassemble it — and it's the default when you write just JOIN.

When to Use

Linking orders to customer names, products to reviews, employees to departments, invoices to payments.

Challenge

Solve the problem below

Show each review with the product name. Display product name, rating, and comment. Order by rating descending.

Your Query