HTML CSS Bootstrap JavaScript jQuery MySQL PHP Data Mining

MySQL Joins — Introduction

Written by RedoHub Team · Last updated: August 1, 2026

In a relational database, data is intentionally spread across multiple tables. A customers table holds customer information. An orders table holds order information. They are separate — but related. A JOIN is the SQL mechanism that brings related rows from two or more tables together into a single result set, based on a matching column.

Without joins, you would have to run multiple separate queries and combine the results manually in your application code. With joins, MySQL does the work for you in one query.


Why Joins Exist

Good database design avoids storing the same information in multiple places. Instead of repeating a customer's name and address inside every order row, you store the customer once in a customers table and reference them by ID in the orders table. When you need a report that shows both the order details and the customer name, a JOIN reunites that data.

customers
orders
Two related tables joined on a shared key (customer_id)

The Sample Tables

All JOIN lessons in this section use the following two tables:

customers

idnamecity
1Rahim UddinDhaka
2Sara BegumChittagong
3Karim AliSylhet
4Nila AkterDhaka

orders

idcustomer_idamountorder_date
112500.002025-06-01
211200.002025-06-05
334800.002025-06-08
46900.002025-06-10

Notice that:

  • Customer id=1 (Rahim) has two orders.
  • Customer id=3 (Karim) has one order.
  • Customers id=2 and id=4 have no orders.
  • Order id=4 references customer_id=6, which does not exist in the customers table.

These gaps and mismatches are exactly what makes the different join types behave differently.


The JOIN Syntax

The general pattern for any join is:

SELECT columns
FROM table_a
[JOIN TYPE] JOIN table_b ON table_a.column = table_b.column;

The ON clause defines the relationship — which column in each table should be matched. Usually this is a primary key from one table and a foreign key from the other.


Types of Joins

INNER JOIN

Returns only rows where there is a match in both tables. Rows from either table that have no match are excluded.

LEFT JOIN

Returns all rows from the left table and matching rows from the right. Unmatched right-side columns become NULL.

RIGHT JOIN

Returns all rows from the right table and matching rows from the left. Unmatched left-side columns become NULL.

CROSS JOIN

Returns the Cartesian product — every row from the left table paired with every row from the right. No matching condition required.

Note: MySQL does not have a native FULL OUTER JOIN, but it can be simulated by combining a LEFT JOIN and a RIGHT JOIN with UNION.

Using Table Aliases in Joins

When joining tables, always use short aliases — they make your query much easier to write and read:

-- Without aliases: verbose
SELECT customers.name, orders.amount
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;

-- With aliases: clean
SELECT c.name, o.amount
FROM customers AS c
INNER JOIN orders AS o ON c.id = o.customer_id;
Convention: Use the first letter of the table name as the alias — c for customers, o for orders. For multiple tables starting with the same letter, use c1, c2 or meaningful abbreviations.

Key Points to Remember

  • A JOIN combines columns from two or more tables into a single result set based on a matching condition.
  • The ON clause specifies which columns to match — typically a primary key and a foreign key.
  • The four main join types are INNER JOIN, LEFT JOIN, RIGHT JOIN, and CROSS JOIN.
  • Always use table aliases when writing joins — it keeps the query concise.
  • The type of join you choose determines which rows appear when there is no match on one side.
What's next? The next lesson covers INNER JOIN — the most commonly used join type, which returns only rows where both tables have a matching value.

Common Mistakes to Avoid

Forgetting the ON clause entirely. A join without a matching condition produces a Cartesian product — every row from one table paired with every row from the other — which can silently return millions of unintended rows on real-sized tables.
Joining on columns of different data types. Comparing a VARCHAR customer ID to an INT foreign key can force MySQL to convert types on every row, sometimes preventing an index from being used at all.
Not using table aliases once a query has two or more tables. Without aliases, repeating full table names in every column reference and the ON clause makes queries hard to read and easy to mistype.

Try It: Spotting an Unwanted Cartesian Product

A second example — comparing a correct join against the mistake of a missing ON clause, using the sample tables from this page:

-- Correct: matched pairs only
SELECT c.name, o.amount
FROM customers AS c
JOIN orders AS o ON c.id = o.customer_id;

-- Mistake: no ON clause -- returns every customer paired with every order
SELECT c.name, o.amount
FROM customers AS c, orders AS o;

Frequently Asked Questions

Q: Do I have to write "INNER JOIN" or is "JOIN" enough?

A: Plain JOIN defaults to INNER JOIN in MySQL — both are identical. Writing INNER explicitly is just a readability preference.

Q: Can I join more than two tables?

A: Yes — chain multiple JOIN ... ON ... clauses in a single query, joining as many tables as the report needs.

Q: Which join type should I reach for by default?

A: INNER JOIN for most reporting queries where you only want matched rows. See the official JOIN documentation for the full syntax of every join type.