PostgreSQL FULL OUTER JOIN
A FULL OUTER JOIN
returns all rows from both tables, with matching rows from both sides wherever available. If there is no match, the result will contain NULL
columns from the table without a matching row.
- The key feature of
FULL OUTER JOIN
is that it includes all rows from both tables, regardless of whether a match exists between them.

1. Syntax of FULL OUTER JOIN
table1.column
and table2.column
are the columns used to match the rows between the two tables.
2. Example 1: Simple FULL OUTER JOIN
Scenario:
Let’s assume we have two tables:
employees
Table:
employee_id | name |
---|
1 | Alice |
2 | Bob |
3 | Charlie |
departments
Table:
department_id | department_name |
---|
1 | HR |
2 | IT |
4 | Marketing |
Query: Get All Employees and Departments, Even if They Don’t Match
Result:
name | department_name |
---|
Alice | NULL |
Bob | NULL |
Charlie | NULL |
NULL | HR |
NULL | IT |
NULL | Marketing |
- Explanation:
- The query matches rows based on
employee_id
(from employees
) and department_id
(from departments
). - Since there are no matching
employee_id
and department_id
, the result contains NULL
for columns from the table without a match.
3. Example 2: FULL OUTER JOIN
with Matching Rows
Scenario:
Consider the orders
table:
orders
Table:
order_id | product_name | customer_id |
---|
101 | Laptop | 1 |
102 | Phone | 2 |
103 | Tablet | NULL |
customers
Table:
customer_id | customer_name |
---|
1 | Alice |
2 | Bob |
4 | Charlie |
Query: Get All Orders and Customers, Including Orders Without Customers
Result:
order_id | product_name | customer_name |
---|
101 | Laptop | Alice |
102 | Phone | Bob |
103 | Tablet | NULL |
NULL | NULL | Charlie |
- Explanation:
- The first two rows match
orders.customer_id
with customers.customer_id
. - The third row (
order_id = 103
) doesn’t have a matching customer_id
, so the result shows NULL
for the customer_name
. - The fourth row (
customer_id = 4
) has no matching order, so the result shows NULL
for the order_id
and product_name
.
4. Example 3: FULL OUTER JOIN
with Both Tables Having Non-Matching Rows
Scenario:
Consider the employees
table:
employees
Table:
employee_id | employee_name |
---|
1 | Alice |
2 | Bob |
projects
Table:
project_id | project_name | employee_id |
---|
101 | Project A | 1 |
102 | Project B | 3 |
Query: Get All Employees and Projects, Even If There Is No Match
Result:
employee_name | project_name |
---|
Alice | Project A |
Bob | NULL |
NULL | Project B |
- Explanation:
- The first row matches
employee_id = 1
with project_id = 101
for Alice
. - The second row shows
Bob
with NULL
for project_name
because there is no project for Bob
. - The third row shows
NULL
for employee_name
and Project B
because there is no employee assigned to that project.
5. Key Points to Remember
- Matching Rows:
FULL OUTER JOIN
returns rows where there is a match based on the specified column(s). - Non-Matching Rows: It also returns rows that do not match from both the left and right tables, filling in
NULL
for missing columns. - More Efficient than Multiple
LEFT JOIN
/RIGHT JOIN
: When you need all rows from both tables, a FULL OUTER JOIN
is more efficient than doing multiple LEFT JOIN
and RIGHT JOIN
queries.
6. Performance Considerations
- Complexity:
FULL OUTER JOIN
can be computationally expensive, especially when joining large tables, as it must find all possible matches between rows. - Indexes: Consider indexing the columns used in the
ON
clause to optimize performance.
7. Summary of FULL OUTER JOIN
Join Type | Description |
---|
FULL OUTER JOIN | Returns all rows from both tables. If there is no match, NULL values are filled in for missing columns. |
Use Case | Useful when you need all records from both tables, regardless of whether a match exists. |
Performance | May be slower on large tables, as it needs to match and include all rows from both tables. |
Would you like to dive into more advanced use cases with FULL OUTER JOIN
, or see a complex example? 🚀