Back to HomeSQL

SQL JOIN Complete Tutorial: INNER, LEFT, RIGHT, FULL JOIN Illustrated [2025]

12 min min read
#SQL#JOIN#INNER JOIN#LEFT JOIN#RIGHT JOIN#FULL JOIN#Database Query

SQL JOIN Complete Tutorial: INNER, LEFT, RIGHT, FULL JOIN Illustrated [2025]

SQL JOIN Complete Tutorial: INNER, LEFT, RIGHT, FULL JOIN Illustrated [2025]

In real database applications, data is usually distributed across multiple related tables. For example, customer data exists in the "Customers" table, order data in the "Orders" table, and product data in the "Products" table. When you need to query "what products a customer purchased," you must "join" these tables together—this is the core purpose of SQL JOIN.

This article will comprehensively introduce all types of SQL JOIN with illustrations and actual code examples, helping you intuitively understand the differences and use cases for each JOIN type. Whether you're a beginner learning SQL or a developer wanting to review JOIN syntax, you'll gain clear concepts from this article.


JOIN Concepts and Use Cases

What is JOIN?

JOIN is an operation in SQL used to combine data from two or more tables. By specifying the relationship conditions between tables (usually common fields like foreign keys), JOIN can integrate distributed data into a single query result.

Sample Data Preparation

To clearly demonstrate the differences between various JOINs, let's create two simple sample tables:

Employees Table:

EmployeeIDNameDepartmentID
1Alice101
2Bob102
3Carol101
4DavidNULL

Departments Table:

DepartmentIDDepartmentName
101R&D
102Marketing
103Finance

Note: David has no assigned department (DepartmentID is NULL), and Finance (103) has no employees.

JOIN Types Overview

JOIN TypeDescriptionReturned Data
INNER JOINInner joinOnly returns data with matches in both tables
LEFT JOINLeft outer joinReturns all data from left table + matched data from right table
RIGHT JOINRight outer joinReturns all data from right table + matched data from left table
FULL OUTER JOINFull outer joinReturns all data from both tables
CROSS JOINCross joinReturns Cartesian product of both tables
Self JoinSelf joinTable joins with itself

INNER JOIN

INNER JOIN is the most commonly used JOIN type, returning only rows that have matching data in both tables. If either side has no corresponding data, that row won't appear in the results.

Syntax Structure

SELECT column_list
FROM TableA
INNER JOIN TableB
ON TableA.related_column = TableB.related_column;

Illustration

    TableA              TableB
  ┌───────┐          ┌───────┐
  │       │          │       │
  │   ████████████████████   │
  │   █  Intersection █   │
  │   ████████████████████   │
  │       │          │       │
  └───────┘          └───────┘

  INNER JOIN returns only the intersection (data with matches on both sides)

Practical Example

-- Query all employees with departments and their department names
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentName
FROM Employees e
INNER JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

Query Result:

EmployeeIDNameDepartmentName
1AliceR&D
2BobMarketing
3CarolR&D

Explanation: David doesn't appear in the results because he has no department (DepartmentID is NULL). Finance doesn't appear because it has no employees.

When to Use

  • When you only need records that have corresponding data in both tables
  • To exclude data without matches in either table
  • Examples: Query "customers with orders," "employees assigned to departments"

LEFT JOIN

LEFT JOIN (or LEFT OUTER JOIN) returns all data from the left table, along with matched data from the right table. If the right table has no match, corresponding columns show NULL.

Syntax Structure

SELECT column_list
FROM TableA
LEFT JOIN TableB
ON TableA.related_column = TableB.related_column;

Illustration

    TableA              TableB
  ┌───────┐          ┌───────┐
  │███████│          │       │
  │███████████████████████   │
  │███████ Intersection ██   │
  │███████████████████████   │
  │███████│          │       │
  └───────┘          └───────┘

  LEFT JOIN returns all of left table + intersection

Practical Example

-- Query all employees and their departments (including employees without departments)
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentName
FROM Employees e
LEFT JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

Query Result:

EmployeeIDNameDepartmentName
1AliceR&D
2BobMarketing
3CarolR&D
4DavidNULL

Explanation: David appears in the results because he's in the left table (Employees), even though he has no department. DepartmentName shows NULL.

Finding Unmatched Data

LEFT JOIN is commonly used to find data that's "in left table but not in right table":

-- Query employees without assigned departments
SELECT
    e.EmployeeID,
    e.Name
FROM Employees e
LEFT JOIN Departments d
ON e.DepartmentID = d.DepartmentID
WHERE d.DepartmentID IS NULL;

Result: Only returns David

When to Use

  • When you need to preserve all data from the left table, even if right table has no match
  • To find records "without related data"
  • Examples: Query "all customers and their orders (including customers without orders)," "all products and their sales records (including unsold products)"

RIGHT JOIN

RIGHT JOIN (or RIGHT OUTER JOIN) is opposite to LEFT JOIN, returning all data from the right table, along with matched data from the left table.

Syntax Structure

SELECT column_list
FROM TableA
RIGHT JOIN TableB
ON TableA.related_column = TableB.related_column;

Illustration

    TableA              TableB
  ┌───────┐          ┌───────┐
  │       │          │███████│
  │   ███████████████████████│
  │   ██ Intersection ███████│
  │   ███████████████████████│
  │       │          │███████│
  └───────┘          └───────┘

  RIGHT JOIN returns intersection + all of right table

Practical Example

-- Query all departments and their employees (including departments without employees)
SELECT
    d.DepartmentID,
    d.DepartmentName,
    e.Name
FROM Employees e
RIGHT JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

Query Result:

DepartmentIDDepartmentNameName
101R&DAlice
101R&DCarol
102MarketingBob
103FinanceNULL

Explanation: Finance (103) appears in the results because it's in the right table (Departments), even though it has no employees.

Practical Recommendation

In practice, most developers prefer using LEFT JOIN because the reading order is more intuitive (main table first, then related table). RIGHT JOIN can usually be rewritten as LEFT JOIN by swapping table order:

-- The following two queries produce the same result
-- Using RIGHT JOIN
SELECT * FROM Employees e RIGHT JOIN Departments d ON e.DepartmentID = d.DepartmentID;

-- Rewritten as LEFT JOIN (recommended)
SELECT * FROM Departments d LEFT JOIN Employees e ON d.DepartmentID = e.DepartmentID;

FULL OUTER JOIN

FULL OUTER JOIN returns all data from both tables, regardless of whether there's a match. Unmatched parts show NULL.

Syntax Structure

SELECT column_list
FROM TableA
FULL OUTER JOIN TableB
ON TableA.related_column = TableB.related_column;

Note: MySQL doesn't directly support FULL OUTER JOIN; you need to use UNION to simulate it.

Illustration

    TableA              TableB
  ┌───────┐          ┌───────┐
  │███████│          │███████│
  │███████████████████████████│
  │███████ Intersection ██████│
  │███████████████████████████│
  │███████│          │███████│
  └───────┘          └───────┘

  FULL OUTER JOIN returns all data from both tables

Practical Example

-- SQL Server / PostgreSQL syntax
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentID,
    d.DepartmentName
FROM Employees e
FULL OUTER JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

Query Result:

EmployeeIDNameDepartmentIDDepartmentName
1Alice101R&D
2Bob102Marketing
3Carol101R&D
4DavidNULLNULL
NULLNULL103Finance

MySQL Simulating FULL OUTER JOIN

-- MySQL doesn't support FULL OUTER JOIN, use UNION to simulate
SELECT e.EmployeeID, e.Name, d.DepartmentID, d.DepartmentName
FROM Employees e
LEFT JOIN Departments d ON e.DepartmentID = d.DepartmentID

UNION

SELECT e.EmployeeID, e.Name, d.DepartmentID, d.DepartmentName
FROM Employees e
RIGHT JOIN Departments d ON e.DepartmentID = d.DepartmentID;

When to Use

  • When you need to completely display all data from both tables
  • Analyzing differences between two data sets
  • Example: Comparing data integrity between two systems

CROSS JOIN

CROSS JOIN produces the Cartesian Product of two tables, meaning all combinations of every row from the left table with every row from the right table.

Syntax Structure

-- Syntax 1: Explicitly use CROSS JOIN
SELECT column_list
FROM TableA
CROSS JOIN TableB;

-- Syntax 2: Implicit syntax
SELECT column_list
FROM TableA, TableB;

Practical Example

-- Generate all combinations of all employees with all departments
SELECT
    e.Name,
    d.DepartmentName
FROM Employees e
CROSS JOIN Departments d;

Query Result: 4 employees × 3 departments = 12 results

NameDepartmentName
AliceR&D
AliceMarketing
AliceFinance
BobR&D
BobMarketing
BobFinance
......

When to Use

  • Generating all possible combinations
  • Test data generation
  • Example: Generate "all sizes × all colors" product combinations

Caution: CROSS JOIN produces large amounts of data (m × n rows). Use carefully and avoid using on large tables.


Self Join

Self Join is a special application where a table joins with itself, used to handle data with hierarchical relationships (like employees and managers, categories and subcategories).

Sample Data

Employees Table (with Manager column):

EmployeeIDNameManagerID
1AliceNULL
2Bob1
3Carol1
4David2

Practical Example

-- Query each employee and their manager's name
SELECT
    e.Name AS EmployeeName,
    m.Name AS ManagerName
FROM Employees e
LEFT JOIN Employees m
ON e.ManagerID = m.EmployeeID;

Query Result:

EmployeeNameManagerName
AliceNULL
BobAlice
CarolAlice
DavidBob

When to Use

  • When table has self-referencing relationships (like ManagerID pointing to EmployeeID in same table)
  • Handling hierarchical structure data
  • Examples: Organization charts, product categories, comment replies

Multi-Table JOIN and Performance Considerations

Multi-Table JOIN Syntax

In practice, you often need to join three or more tables:

-- Query order details: customer name, order ID, product name
SELECT
    c.CustomerName,
    o.OrderID,
    o.OrderDate,
    p.ProductName,
    od.Quantity
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
WHERE o.OrderDate >= '2025-01-01';

JOIN Performance Optimization Tips

Optimization DirectionDescription
Create indexesCreate indexes on JOIN columns (usually foreign keys)
Filter before JOINUse WHERE or subqueries to narrow data scope first
**Avoid SELECT ***Only select needed columns, reduce data transfer
Small table drives large tablePut smaller data volume tables on left side of JOIN
Review execution planUse EXPLAIN to analyze query performance
-- Index creation example
CREATE INDEX idx_orders_customerid ON Orders(CustomerID);
CREATE INDEX idx_orderdetails_orderid ON OrderDetails(OrderID);

FAQ

Q1: What's the Difference Between LEFT JOIN and RIGHT JOIN?

LEFT JOIN preserves all data from the left table, RIGHT JOIN preserves all data from the right table. With FROM A LEFT JOIN B, even if table B has no corresponding data, all data from table A still appears with NULL for table B columns. Conversely, FROM A RIGHT JOIN B preserves all data from table B. In practice, most developers prefer LEFT JOIN because the reading order is more intuitive (main table first). If you need RIGHT JOIN's effect, you can swap table order and use LEFT JOIN.

Q2: When Should I Use INNER JOIN?

Use INNER JOIN when you only need records that have corresponding data in both tables. For example: querying "customers with orders"—if a customer has no orders and you don't want them in the results, use INNER JOIN. Conversely, if you need "all customers, including those without orders," use LEFT JOIN. Simple rule: If you can accept some rows "disappearing" because there's no match, use INNER JOIN; if you need to preserve complete data from one side, use LEFT/RIGHT JOIN.


Further Learning Resources

For deeper SQL query skills, refer to these resources:

SQL Basic Syntax:

Advanced Query Techniques:


Conclusion

SQL JOIN is a core skill for database queries. Mastering the differences between various JOIN types enables you to flexibly handle various multi-table query needs. Quick summary:

  • INNER JOIN: Only intersection, returns only when both sides have matches
  • LEFT JOIN: Preserves all left table, shows NULL if right table has no match
  • RIGHT JOIN: Preserves all right table, shows NULL if left table has no match
  • FULL OUTER JOIN: Preserves both sides completely
  • CROSS JOIN: Produces all combinations (Cartesian product)
  • Self Join: Table joins with itself, handles hierarchical relationships

Recommend starting with INNER JOIN and LEFT JOIN practice—these two cover over 90% of practical needs. After mastering them, learn other JOIN types to progressively improve your SQL query capabilities.


Want Quick Reference for JOIN Syntax? — Download our organized SQL JOIN quick reference illustration, including Venn Diagrams and syntax examples for all JOIN types. Print it out and keep it on your desk for easy reference.

Free Download SQL JOIN Quick Reference PDF →


References

Need Professional Cloud Advice?

Whether you're evaluating cloud platforms, optimizing existing architecture, or looking for cost-saving solutions, we can help

Book Free Consultation

Related Articles