Lesson 50 of 60 – FULL OUTER JOIN
83%

SQL FULL OUTER JOIN

A FULL OUTER JOIN combines the results of a LEFT JOIN and a RIGHT JOIN. It returns all records from both tables. Matching records are combined, while unmatched records from either table contain NULL values for the missing side.

Note: MySQL does not directly support the FULL OUTER JOIN keyword. In MySQL, it can commonly be simulated using LEFT JOIN, RIGHT JOIN, and UNION.

1. What is FULL OUTER JOIN?

A FULL OUTER JOIN returns all records from both tables.

SELECT *
FROM table1
FULL OUTER JOIN table2
ON table1.id = table2.id;

Matching records are combined, while unmatched records from either table are also included.

2. Basic FULL OUTER JOIN Syntax

The standard SQL syntax is:

SELECT columns
FROM table1
FULL OUTER JOIN table2
ON table1.column = table2.column;

The exact syntax supported depends on the database system.

3. FULL OUTER JOIN in MySQL

MySQL does not provide a native FULL OUTER JOIN operator. A common solution is to combine LEFT JOIN and RIGHT JOIN using UNION.

SELECT
    s.student_name,
    c.course_name
FROM students AS s
LEFT JOIN courses AS c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students AS s
RIGHT JOIN courses AS c
ON s.course_id = c.id;

4. Why Use FULL OUTER JOIN?

FULL OUTER JOIN is useful when you want to see every record from both tables, including records that do not have a match.

For example, it can help compare:

  • Students and courses
  • Employees and departments
  • Customers and orders
  • Products and sales

5. Matching Records

When a record exists in both tables with a matching value, the information from both tables is combined.

SELECT
    s.student_name,
    c.course_name
FROM students AS s
LEFT JOIN courses AS c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students AS s
RIGHT JOIN courses AS c
ON s.course_id = c.id;

6. Unmatched Records from the Left Table

A FULL OUTER JOIN includes records from the left table even when there is no matching record in the right table.

The columns belonging to the right table will contain NULL.

Student: Rahul
Course ID: 10

Matching Course:
Not Found

7. Unmatched Records from the Right Table

It also includes records from the right table that have no matching record in the left table.

The columns belonging to the left table will contain NULL.

Course: Python
Course ID: 20

Matching Student:
Not Found

8. FULL OUTER JOIN Using UNION

In MySQL, LEFT JOIN and RIGHT JOIN can be combined using UNION.

SELECT
    s.student_name,
    c.course_name
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

9. FULL OUTER JOIN Using UNION ALL

UNION ALL can also be used, but it may return duplicate matching rows.

SELECT
    s.student_name,
    c.course_name
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION ALL

SELECT
    s.student_name,
    c.course_name
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

Use UNION when duplicate matching rows should be removed.

10. FULL OUTER JOIN vs INNER JOIN

INNER JOIN: Returns only matching records.

FULL OUTER JOIN: Returns matching and unmatched records from both tables.

-- INNER JOIN
SELECT *
FROM students s
INNER JOIN courses c
ON s.course_id = c.id;

11. FULL OUTER JOIN vs LEFT JOIN

LEFT JOIN: Keeps all records from the left table.

FULL OUTER JOIN: Keeps all records from both tables.

-- LEFT JOIN
SELECT *
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id;

12. FULL OUTER JOIN vs RIGHT JOIN

RIGHT JOIN: Keeps all records from the right table.

FULL OUTER JOIN: Keeps all records from both tables.

-- RIGHT JOIN
SELECT *
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

13. FULL OUTER JOIN and NULL Values

NULL values are expected when a record exists on one side but has no matching record on the other side.

Student Name    Course Name
-------------   -----------
Rahul           Python
Amit            NULL
NULL            Java

Here, Amit has no matching course and Java has no matching student.

14. Finding Unmatched Records

A FULL OUTER JOIN can be used to identify records that exist on only one side.

SELECT
    s.student_name,
    c.course_name
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

15. FULL OUTER JOIN with Table Aliases

Aliases make FULL OUTER JOIN simulations easier to read.

SELECT
    s.student_name,
    c.course_name
FROM students AS s
LEFT JOIN courses AS c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students AS s
RIGHT JOIN courses AS c
ON s.course_id = c.id;

16. FULL OUTER JOIN with Three Tables

A FULL OUTER JOIN concept can be extended to more tables by combining appropriate joins.

SELECT
    s.student_name,
    c.course_name,
    p.amount
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id
LEFT JOIN payments p
ON s.id = p.student_id

UNION

SELECT
    s.student_name,
    c.course_name,
    p.amount
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id
LEFT JOIN payments p
ON s.id = p.student_id;

17. FULL OUTER JOIN with COALESCE()

COALESCE() can be used to display a value from either table when one side is NULL.

SELECT
    COALESCE(s.student_name, 'No Student') AS student,
    COALESCE(c.course_name, 'No Course') AS course
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    COALESCE(s.student_name, 'No Student') AS student,
    COALESCE(c.course_name, 'No Course') AS course
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

18. FULL OUTER JOIN with CASE

CASE can be used to identify whether a record exists on one or both sides.

SELECT
    s.student_name,
    c.course_name,
    CASE
        WHEN s.id IS NULL THEN 'Only in Courses'
        WHEN c.id IS NULL THEN 'Only in Students'
        ELSE 'Matched'
    END AS match_status
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name,
    CASE
        WHEN s.id IS NULL THEN 'Only in Courses'
        WHEN c.id IS NULL THEN 'Only in Students'
        ELSE 'Matched'
    END AS match_status
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

19. FULL OUTER JOIN with ORDER BY

The combined result can be sorted.

SELECT
    s.student_name,
    c.course_name
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id
ORDER BY student_name;

20. FULL OUTER JOIN with WHERE

Filtering can be applied to the combined result.

SELECT
    student_name,
    course_name
FROM
(
    SELECT
        s.student_name,
        c.course_name
    FROM students s
    LEFT JOIN courses c
    ON s.course_id = c.id

    UNION

    SELECT
        s.student_name,
        c.course_name
    FROM students s
    RIGHT JOIN courses c
    ON s.course_id = c.id
) AS combined_data
WHERE course_name IS NULL;

This example finds records where course information is missing.

21. FULL OUTER JOIN with GROUP BY

The combined result can be grouped for reporting.

SELECT
    course_name,
    COUNT(*) AS total_records
FROM
(
    SELECT
        s.student_name,
        c.course_name
    FROM students s
    LEFT JOIN courses c
    ON s.course_id = c.id

    UNION

    SELECT
        s.student_name,
        c.course_name
    FROM students s
    RIGHT JOIN courses c
    ON s.course_id = c.id
) AS combined_data
GROUP BY course_name;

22. FULL OUTER JOIN for Data Comparison

FULL OUTER JOIN is useful when comparing two datasets.

For example:

  • Old student records vs new student records
  • Current products vs previous products
  • Employees in two departments
  • Customers in two systems

It helps identify matching and missing records.

23. FULL OUTER JOIN for Student Comparison

Suppose we have two student lists and want to compare them.

SELECT
    old_students.student_name,
    new_students.student_name
FROM old_students
LEFT JOIN new_students
ON old_students.student_id = new_students.student_id

UNION

SELECT
    old_students.student_name,
    new_students.student_name
FROM old_students
RIGHT JOIN new_students
ON old_students.student_id = new_students.student_id;

24. FULL OUTER JOIN for Employee Comparison

The same technique can compare employee records.

SELECT
    a.employee_id,
    a.employee_name,
    b.employee_name AS new_name
FROM employees_old AS a
LEFT JOIN employees_new AS b
ON a.employee_id = b.employee_id

UNION

SELECT
    a.employee_id,
    a.employee_name,
    b.employee_name AS new_name
FROM employees_old AS a
RIGHT JOIN employees_new AS b
ON a.employee_id = b.employee_id;

25. FULL OUTER JOIN and UNION

The main idea of simulating FULL OUTER JOIN in MySQL is:

LEFT JOIN
+
RIGHT JOIN
+
UNION

The LEFT JOIN supplies all records from the first table, while the RIGHT JOIN supplies records that exist only on the second side.

26. FULL OUTER JOIN and UNION ALL

UNION removes duplicate rows, while UNION ALL keeps them.

SELECT
    s.student_name,
    c.course_name
FROM students s
LEFT JOIN courses c
ON s.course_id = c.id

UNION

SELECT
    s.student_name,
    c.course_name
FROM students s
RIGHT JOIN courses c
ON s.course_id = c.id;

For a typical FULL OUTER JOIN simulation, UNION is often preferred when duplicate matching rows should not appear twice.

27. Common FULL OUTER JOIN Mistake

A common mistake in MySQL is trying to directly execute:

SELECT *
FROM students
FULL OUTER JOIN courses
ON students.course_id = courses.id;

MySQL does not support the FULL OUTER JOIN keyword directly. Use a LEFT JOIN and RIGHT JOIN combination with UNION instead.

28. FULL OUTER JOIN vs Other JOINs

INNER JOIN: Only matching records.

LEFT JOIN: All records from the left table plus matches.

RIGHT JOIN: All records from the right table plus matches.

FULL OUTER JOIN: All records from both tables.

INNER  → Matching only
LEFT   → Everything from left
RIGHT  → Everything from right
FULL   → Everything from both

29. Practical Student-Course Comparison

The following query can be used to compare student and course records.

SELECT
    s.student_id,
    s.student_name,
    c.id AS course_id,
    c.course_name
FROM students AS s
LEFT JOIN courses AS c
ON s.course_id = c.id

UNION

SELECT
    s.student_id,
    s.student_name,
    c.id AS course_id,
    c.course_name
FROM students AS s
RIGHT JOIN courses AS c
ON s.course_id = c.id;

This keeps information from both sides of the relationship.

30. Complete FULL OUTER JOIN Example

The following example simulates a FULL OUTER JOIN in MySQL and identifies the relationship between students and courses.

SELECT
    s.student_id,
    s.student_name,
    c.id AS course_id,
    c.course_name,
    CASE
        WHEN s.id IS NULL THEN 'Only in Courses'
        WHEN c.id IS NULL THEN 'Only in Students'
        ELSE 'Matched'
    END AS match_status
FROM students AS s
LEFT JOIN courses AS c
ON s.course_id = c.id

UNION

SELECT
    s.student_id,
    s.student_name,
    c.id AS course_id,
    c.course_name,
    CASE
        WHEN s.id IS NULL THEN 'Only in Courses'
        WHEN c.id IS NULL THEN 'Only in Students'
        ELSE 'Matched'
    END AS match_status
FROM students AS s
RIGHT JOIN courses AS c
ON s.course_id = c.id;

This query returns matching students and courses as well as unmatched records from either table.

📌 Key Points

  • FULL OUTER JOIN returns all records from both tables.
  • Matching records are combined into one result.
  • Unmatched records from either table are also returned.
  • Unmatched columns contain NULL.
  • MySQL does not directly support the FULL OUTER JOIN keyword.
  • In MySQL, FULL OUTER JOIN can be simulated using LEFT JOIN, RIGHT JOIN, and UNION.
  • UNION removes duplicate rows.
  • UNION ALL keeps duplicate rows.
  • FULL OUTER JOIN is useful for comparing two datasets.
  • COALESCE() can replace NULL values with readable values.
  • CASE can identify matched and unmatched records.
  • FULL OUTER JOIN returns more records than INNER JOIN when unmatched rows exist.
  • It is useful for data comparison and reconciliation.

🧠 Quick Quiz

Question: Which combination can be used to simulate a FULL OUTER JOIN in MySQL?