SQL FULL JOIN
SQL

SQL FULL JOIN: Combine All Rows from Both Tables (Examples)

SQL Tutorial · Chapter 23 of 32

The SQL FULL JOIN (also written FULL OUTER JOIN) returns every row from both tables. Where a row on either side has no match, the columns from the other table are NULL. It combines the behaviour of LEFT JOIN and RIGHT JOIN in one statement and is the standard way to reconcile two lists and see what is missing from each.

SQL FULL JOIN Syntax

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

OUTER is optional. Because either side can be NULL, wrap key columns in COALESCE when you need a single non-NULL identifier.

Sample Tables

Customers
CustomerID Name City Country
1 Anita Sharma Mumbai India
2 John Smith London UK
3 Maria Garcia Madrid Spain
4 Wei Chen Singapore Singapore
5 Emma Brown Sydney Australia
Orders
OrderID CustomerID Product Amount OrderDate
101 1 Laptop 1200 2026-01-05
102 2 Mouse 25 2026-01-07
103 1 Monitor 300 2026-01-12
104 3 Keyboard 45 2026-02-02
105 6 Headset 80 2026-02-15
106 4 Laptop 1150 2026-03-01

Two rows have no partner: customer 5 (no orders) and order 105 (customer 6 does not exist). A FULL JOIN shows both.

Example 1: Full Join of Customers and Orders

SELECT c.CustomerID, c.Name, o.OrderID, o.Product
FROM Customers c
FULL OUTER JOIN Orders o ON o.CustomerID = c.CustomerID
ORDER BY COALESCE(c.CustomerID, o.CustomerID), o.OrderID;
CustomerID Name OrderID Product
1 Anita Sharma 101 Laptop
1 Anita Sharma 103 Monitor
2 John Smith 102 Mouse
3 Maria Garcia 104 Keyboard
4 Wei Chen 106 Laptop
5 Emma Brown NULL NULL
NULL NULL 105 Headset

Seven rows: five matches, one customer-only row and one order-only row.

Example 2: Show Only the Mismatches

Keeping rows where either key is NULL gives a reconciliation report in one query.

SELECT c.Name, o.OrderID,
       CASE WHEN c.CustomerID IS NULL THEN 'Order without customer'
            ELSE 'Customer without orders' END AS Issue
FROM Customers c
FULL OUTER JOIN Orders o ON o.CustomerID = c.CustomerID
WHERE c.CustomerID IS NULL OR o.OrderID IS NULL;
Name OrderID Issue
Emma Brown NULL Customer without orders
NULL 105 Order without customer

Example 3: Totals That Reconcile

SELECT COALESCE(c.Name, 'Unknown customer') AS Customer,
       COUNT(o.OrderID) AS Orders,
       COALESCE(SUM(o.Amount), 0) AS Total
FROM Customers c
FULL OUTER JOIN Orders o ON o.CustomerID = c.CustomerID
GROUP BY COALESCE(c.Name, 'Unknown customer')
ORDER BY Total DESC;
Customer Orders Total
Anita Sharma 2 1500
Wei Chen 1 1150
Unknown customer 1 80
Maria Garcia 1 45
John Smith 1 25
Emma Brown 0 0

The grand total is 2800, the same as SUM(Amount) on Orders alone: nothing was dropped and nothing was double counted.

Example 4: Emulating FULL JOIN in MySQL

MySQL has no FULL JOIN. Combine a LEFT JOIN and a RIGHT JOIN with UNION, which removes the duplicated matched rows.

SELECT c.Name, o.OrderID
FROM Customers c LEFT JOIN Orders o ON o.CustomerID = c.CustomerID
UNION
SELECT c.Name, o.OrderID
FROM Customers c RIGHT JOIN Orders o ON o.CustomerID = c.CustomerID;

Result: the same seven rows as Example 1. If the two SELECTs could legitimately produce identical rows, use UNION ALL on the LEFT JOIN plus a RIGHT JOIN filtered with WHERE c.CustomerID IS NULL instead.

Works in MySQL, SQL Server, PostgreSQL, SQLite

  • SQL Server and PostgreSQL: FULL OUTER JOIN is fully supported.
  • SQLite: supported from version 3.39; older versions need the UNION workaround.
  • MySQL: not supported in any version; always use the UNION of a LEFT and a RIGHT JOIN.

Common Mistakes

  • Selecting c.CustomerID alone as the key and getting NULL for orphan orders; use COALESCE across both sides.
  • Adding a WHERE condition on one table and unintentionally removing the other side’s unmatched rows.
  • Using UNION ALL in the MySQL emulation and doubling every matched row.
  • Reaching for FULL JOIN when the question is really one-sided; LEFT JOIN is simpler and faster.

Practice Exercise

  1. Count how many rows a FULL JOIN of Customers and Orders returns, and explain each extra row.
  2. Return only customers without orders using a FULL JOIN.
Show answers
-- 1: 7 rows = 5 matched + Emma Brown (no orders) + order 105 (no customer)
SELECT COUNT(*) FROM Customers c FULL OUTER JOIN Orders o ON o.CustomerID = c.CustomerID;

-- 2
SELECT c.Name FROM Customers c
FULL OUTER JOIN Orders o ON o.CustomerID = c.CustomerID
WHERE o.OrderID IS NULL AND c.CustomerID IS NOT NULL;
-- Emma Brown

Related Chapters

FAQ

What is the difference between FULL JOIN and FULL OUTER JOIN?

None. OUTER is optional; both keywords produce the same result.

Does MySQL support FULL OUTER JOIN?

No. Emulate it by combining a LEFT JOIN and a RIGHT JOIN with UNION.

When should I use a FULL JOIN?

When you need to see unmatched rows from both tables at once, such as reconciling two systems, comparing budget with actuals, or auditing referential integrity.

Chapter 23 of 32 · SQL from Scratch: all 32 chapters

PK
Meet PK, the founder of NeotechNavigators.com! With over 15 years of experience in Data Visualization, Excel Automation, and dashboard creation. PK is a Microsoft Certified Professional who has a passion for all things in Excel. PK loves to explore new and innovative ways to use Excel and is always eager to share his knowledge with others. With an eye for detail and a commitment to excellence, PK has become a go-to expert in the world of Excel. Whether you're looking to create stunning visualizations or streamline your workflow with automation, PK has the skills and expertise to help you succeed. Join the many satisfied clients who have benefited from PK's services and see how he can take your data analysis skills to the next level!
https://neotechnavigators.com