Question:
I cannot see any difference in output between left join and full outer join with our example. can u create a new data to see me correct difference between them?
This is actually something that confuses many developers in interviews.
The reason you don’t see any difference is because our current data doesn’t have any “orphan” records in the orders table.
Let’s understand why.
Our Current Data
users
| id | name |
|---|---|
| 1 | John |
| 2 | Mary |
| 3 | Bob |
| 4 | Alice |
orders
| id | user_id | amount |
|---|---|---|
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 2 | 300 |
| 4 | 2 | 400 |
| 5 | 2 | 500 |
Every order belongs to an existing user.
So there are:
- Users without orders (Bob, Alice)
- No orders without users
That’s why LEFT JOIN and FULL OUTER JOIN appear almost identical.
Let’s Create a Better Example
To see the difference, we need an order that doesn’t match any user.
However…
Our foreign key prevents that.
FOREIGN KEY (user_id)REFERENCES users(id)
This is a good thing because it maintains data integrity.
So for learning purposes, we’ll create another table without a foreign key.
Step 1
DROP TABLE IF EXISTS orders_demo;CREATE TABLE orders_demo ( id BIGSERIAL PRIMARY KEY, user_id BIGINT, amount NUMERIC(10,2));
Notice:
❌ No foreign key.
Step 2
Insert data
INSERT INTO orders_demo(user_id, amount)VALUES(1,100),(1,200),(2,300),(999,400);
Now we have:
users
| id | name |
|---|---|
| 1 | John |
| 2 | Mary |
| 3 | Bob |
| 4 | Alice |
orders_demo
| id | user_id | amount |
|---|---|---|
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 2 | 300 |
| 4 | 999 | 400 |
Notice:
user_id = 999
There is no matching user.
This is our orphan order.
INNER JOIN
SELECT u.id, u.name, o.amountFROM users uINNER JOIN orders_demo oON u.id = o.user_id;
Result
| name | amount |
|---|---|
| John | 100 |
| John | 200 |
| Mary | 300 |
The orphan order disappears.
LEFT JOIN
SELECT u.id, u.name, o.amountFROM users uLEFT JOIN orders_demo oON u.id = o.user_id;
Result
| name | amount |
|---|---|
| John | 100 |
| John | 200 |
| Mary | 300 |
| Bob | NULL |
| Alice | NULL |
Question:
Where is the orphan order?
It is gone!
Why?
Because LEFT JOIN keeps every row from the left table (users). Since there is no user with id = 999, there is nothing on the left to preserve.
FULL OUTER JOIN
SELECT u.id, u.name, o.user_id, o.amountFROM users uFULL OUTER JOIN orders_demo oON u.id = o.user_id;
Result
| user id | name | order user_id | amount |
|---|---|---|---|
| 1 | John | 1 | 100 |
| 1 | John | 1 | 200 |
| 2 | Mary | 2 | 300 |
| 3 | Bob | NULL | NULL |
| 4 | Alice | NULL | NULL |
| NULL | NULL | 999 | 400 |
Now you finally see the difference!
The last row exists only because of FULL OUTER JOIN.