SQL Tutorial

SQL Joins – INNER JOIN, LEFT JOIN, RIGHT JOIN & FULL OUTER JOIN with Examples (2026-27)

A SQL JOIN is used to combine rows from two or more tables based on a related column — usually a foreign key in one table matching a primary key in another. Real-world databases rarely store all data in one table — employee names are in one table, department details in another, salary in a third. JOINs let you pull all that data together in a single query. In this beginner-friendly guide you will learn all six SQL JOIN types — INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN, and SELF JOIN — with clear syntax, real examples, a comparison table, and the most common mistakes to avoid.



✅ What is a SQL JOIN?

✅ A SQL JOIN combines rows from two or more tables based on a related column shared between them.

✅ The related column is typically a foreign key in one table and a primary key in another.

✅ Without JOINs, you would need to run multiple separate queries and combine results manually — JOIN does it all in one step.

💡 Real-world example: Your company has an Employees table (ID, Name, DeptID) and a Department table (DeptID, DeptName). To show each employee's name alongside their department name, you JOIN both tables on DeptID — the common column connecting them.

✅ All SQL JOIN Types at a Glance

🔵 INNER JOIN
Returns only rows where there is a match in BOTH tables. Most commonly used JOIN.
⬅️ LEFT JOIN
Returns ALL rows from the left table. Matching rows from the right; NULL where no match.
➡️ RIGHT JOIN
Returns ALL rows from the right table. Matching rows from the left; NULL where no match.
🔄 FULL OUTER JOIN
Returns ALL rows from BOTH tables. NULL where there is no match on either side.
✖️ CROSS JOIN
Returns every possible combination of rows from both tables. No ON condition needed.
🔁 SELF JOIN
Joins a table with itself. Used when rows in the same table relate to each other.

✅ Sample Tables Used in All Examples

Table 1: Employees
EmpIDNameDeptID
1ANNI10
2POOJA20
3RAJ30
4SUJAN40
5MEENANULL
Table 2: Department
DeptIDDeptName
10IT
20HR
30Sales
50Finance
ℹ️ Key observations: SUJAN has DeptID 40 — which does not exist in the Department table. MEENA has no DeptID (NULL). Department 50 (Finance) has no matching employee. These mismatches show clearly why different JOIN types return different results.

✅ INNER JOIN – Only Matching Rows

INNER JOIN returns only rows where there is a matching value in both tables. Rows with no match are excluded.

SELECT Query:-

SELECT E.EmpID, E.Name, D.DeptName
FROM Employees E
INNER JOIN Department D ON E.DeptID = D.DeptID;

Result:-

Result — Only Employees with Matching Department
EmpIDNameDeptName
1ANNIIT
2POOJAHR
3RAJSales
💡 Why only 3 rows? SUJAN (DeptID 40) has no matching department. MEENA (NULL DeptID) has no match. Finance (DeptID 50) has no matching employee. INNER JOIN excludes all of these — only exact matches appear.

✅ LEFT JOIN – All Left Table + Matching Right

LEFT JOIN returns ALL rows from the left table (Employees), plus matching rows from the right table (Department). Where no match exists, the right table columns show NULL.

SELECT Query:-

SELECT E.EmpID, E.Name, D.DeptName
FROM Employees E
LEFT JOIN Department D ON E.DeptID = D.DeptID;

Result:-

Result — All Employees, NULL Where No Dept Match
EmpIDNameDeptName
1ANNIIT
2POOJAHR
3RAJSales
4SUJANNULL
5MEENANULL
ℹ️ Explanation: All 5 employees appear (left table is complete). SUJAN and MEENA have no matching department — DeptName shows NULL. Finance (DeptID 50) does not appear because it has no matching employee.

✅ RIGHT JOIN – All Right Table + Matching Left

RIGHT JOIN returns ALL rows from the right table (Department), plus matching rows from the left table (Employees). Where no match exists, the left table columns show NULL.

SELECT Query:-

SELECT E.EmpID, E.Name, D.DeptName
FROM Employees E
RIGHT JOIN Department D ON E.DeptID = D.DeptID;

Result:-

Result — All Departments, NULL Where No Employee Match
EmpIDNameDeptName
1ANNIIT
2POOJAHR
3RAJSales
NULLNULLFinance
ℹ️ Explanation: All 4 departments appear (right table is complete). Finance has no matching employee — EmpID and Name show NULL. SUJAN and MEENA do not appear because their DeptIDs (40, NULL) have no matching department.

✅ FULL OUTER JOIN – All Rows from Both Tables

FULL OUTER JOIN returns ALL rows from both tables. Matching rows are combined; non-matching rows from either side show NULL for the other table's columns.

SELECT Query:-

SELECT E.EmpID, E.Name, D.DeptName
FROM Employees E
FULL OUTER JOIN Department D ON E.DeptID = D.DeptID;

Result:-

Result — All Rows from Both Tables
EmpIDNameDeptName
1ANNIIT
2POOJAHR
3RAJSales
4SUJANNULL
5MEENANULL
NULLNULLFinance
⚠️ MySQL does not support FULL OUTER JOIN directly. In MySQL, simulate it by using UNION of a LEFT JOIN and a RIGHT JOIN:
SELECT ... FROM Employees LEFT JOIN Department ... UNION SELECT ... FROM Employees RIGHT JOIN Department ...

✅ CROSS JOIN – Every Possible Combination

CROSS JOIN returns the Cartesian product — every row from the left table paired with every row from the right table. No ON condition is used.

SELECT Query:-

SELECT E.Name, D.DeptName
FROM Employees E
CROSS JOIN Department D;
💡 Result size: 5 employees × 4 departments = 20 rows. Every employee is paired with every department — regardless of any relationship. CROSS JOIN is rarely used in practice but useful for generating test data or combination lists.
⚠️ Warning: CROSS JOIN on large tables can produce millions of rows instantly, causing severe performance problems. Always add a WHERE clause or be very deliberate when using CROSS JOIN in production.

✅ SELF JOIN – Table Joined with Itself

A SELF JOIN joins a table with itself using table aliases. Common use case: finding employee-manager relationships in the same table.

Extended Employees Table with ManagerID:-

Employees (with ManagerID)
EmpIDNameManagerID
1ANNINULL
2POOJA1
3RAJ1
4SUJAN2
5MEENA2

SELECT Query — Show Each Employee and Their Manager Name:-

SELECT E.Name AS Employee, M.Name AS Manager
FROM Employees E
LEFT JOIN Employees M ON E.ManagerID = M.EmpID;

Result:-

Result — Employees with Their Managers
EmployeeManager
ANNINULL
POOJAANNI
RAJANNI
SUJANPOOJA
MEENAPOOJA
ℹ️ How it works: The Employees table is joined with itself — once as the employee (alias E) and once as the manager (alias M). ANNI has no manager (NULL ManagerID) so she shows NULL. POOJA and RAJ report to ANNI. SUJAN and MEENA report to POOJA.

✅ JOIN Type Comparison Table

JOIN TypeReturns Left Unmatched?Returns Right Unmatched?Only Matches?Use Case
INNER JOIN❌ No❌ No✅ YesCommon data in both tables
LEFT JOIN✅ Yes (NULL right)❌ No✅ YesAll left + matches
RIGHT JOIN❌ No✅ Yes (NULL left)✅ YesAll right + matches
FULL OUTER JOIN✅ Yes✅ Yes✅ YesAll rows both tables
CROSS JOINN/AN/AN/ACartesian product
SELF JOINDepends on JOIN type usedDepends on JOIN type usedDependsHierarchical / self-referencing data

✅ Key Points to Remember

✅ INNER JOIN — most used; returns only rows with a match in both tables.

✅ LEFT JOIN — use when you want all records from the left table regardless of matches.

✅ RIGHT JOIN — mirror of LEFT JOIN; all records from the right table.

✅ FULL OUTER JOIN — all rows from both; NULL fills unmatched sides.

✅ CROSS JOIN — every combination; result size = rows left × rows right.

✅ SELF JOIN — join a table with itself; always use aliases (E, M, etc.).

✅ Always use aliases — makes multi-table queries readable: FROM Employees E JOIN Department D ON E.DeptID = D.DeptID.

✅ MySQL workaround — MySQL does not support FULL OUTER JOIN; use UNION of LEFT and RIGHT JOIN instead.


✅ Common SQL JOIN Mistakes to Avoid

❌ Mistake 1: Forgetting the ON condition
Wrong: SELECT * FROM Employees JOIN Department; — this is a CROSS JOIN producing millions of rows.
Correct: SELECT * FROM Employees JOIN Department ON Employees.DeptID = Department.DeptID;
❌ Mistake 2: Joining on the wrong column
Always join on the column that logically connects the tables — usually the foreign key in one table and primary key in the other. Joining on unrelated columns produces meaningless results.
❌ Mistake 3: Ambiguous column names without aliases
Wrong: SELECT DeptID FROM Employees JOIN Department ON ... — SQL doesn't know which table's DeptID you want.
Correct: SELECT E.DeptID FROM Employees E JOIN Department D ON E.DeptID = D.DeptID;
❌ Mistake 4: Using FULL OUTER JOIN in MySQL
MySQL does not support FULL OUTER JOIN. Attempting it gives a syntax error. Use LEFT JOIN UNION RIGHT JOIN to simulate the same result in MySQL.

✅ Frequently Asked Questions (FAQ)

What is a SQL JOIN?
A SQL JOIN combines rows from two or more tables based on a related column — usually a foreign key in one table matching a primary key in another. It lets you retrieve data from multiple tables in a single query.
What is the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows where there is a match in BOTH tables. LEFT JOIN returns ALL rows from the left table, plus matching rows from the right table — rows with no match in the right table show NULL for the right table columns.
What is the difference between LEFT JOIN and RIGHT JOIN?
LEFT JOIN returns all rows from the LEFT table and matching rows from the right. RIGHT JOIN returns all rows from the RIGHT table and matching rows from the left. They are mirror images — swapping the table order in a LEFT JOIN gives the same result as a RIGHT JOIN.
What does FULL OUTER JOIN do in SQL?
FULL OUTER JOIN returns ALL rows from BOTH tables — matching rows are combined, and non-matching rows from either table show NULL for the columns of the other table. It is the combination of LEFT JOIN and RIGHT JOIN results. Note: MySQL does not support FULL OUTER JOIN directly.
Can I join more than two tables in SQL?
Yes. You can chain multiple JOINs: SELECT * FROM Employees E JOIN Department D ON E.DeptID = D.DeptID JOIN Location L ON D.LocID = L.LocID; Each JOIN adds another table to the result set.
What is a SELF JOIN in SQL?
A SELF JOIN joins a table with itself. It is used when rows in the same table are related to each other — for example, an Employees table where each employee has a ManagerID that refers to another employee in the same table. Always use table aliases when writing a SELF JOIN.

✍️ About the Author: Pramod Behera

Pramod Behera is a SAP and SQL educator with 10+ years of experience in enterprise software and database systems. He founded LearnToSAP.com to help beginners learn SAP and SQL concepts through clear, practical, real-world examples. His tutorials have helped thousands of students and IT professionals across India and beyond.