LEFT JOIN vs LEFT OUTER JOIN: Is There a Difference?
No. LEFT JOIN and LEFT OUTER JOIN are exactly the same thing. The word "OUTER" is optional and changes nothing about the behavior. Every SQL database treats them identically.
-- These two queries produce identical results
SELECT c.name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
SELECT c.name, o.order_id
FROM customers c
LEFT OUTER JOIN orders o ON c.id = o.customer_id;
The SQL standard includes the OUTER keyword for readability, but most developers omit it because it adds noise without adding meaning.
Why Both Forms Exist
The SQL specification defines three types of joins by how they handle unmatched rows:
- INNER JOIN (or just JOIN): Only returns rows with matches in both tables
- OUTER JOIN: Returns all rows from one or both tables, filling NULLs where there is no match
"OUTER" distinguishes from "INNER" at the conceptual level. But since LEFT, RIGHT, and FULL already imply outer join behavior, writing "OUTER" is redundant:
| Full Form | Short Form | Same? |
|---|---|---|
| LEFT OUTER JOIN | LEFT JOIN | Yes |
| RIGHT OUTER JOIN | RIGHT JOIN | Yes |
| FULL OUTER JOIN | FULL JOIN | Yes |
| INNER JOIN | JOIN | Yes |
How LEFT JOIN Works
A LEFT JOIN returns:
- All rows from the left table (the one before the JOIN keyword)
- Matching rows from the right table where the ON condition is satisfied
- NULLs for all right-table columns where there is no match
-- Customers table (left) Orders table (right)
-- id | name order_id | customer_id | amount
-- 1 | Alice 101 | 1 | 500
-- 2 | Bob 102 | 1 | 300
-- 3 | Charlie 103 | 3 | 750
SELECT c.name, o.order_id, o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
-- Result:
-- name | order_id | amount
-- Alice | 101 | 500
-- Alice | 102 | 300
-- Bob | NULL | NULL <-- Bob has no orders, still appears
-- Charlie | 103 | 750
Bob appears in the result with NULLs because LEFT JOIN preserves all left-table rows regardless of whether a match exists in the right table.
When to Use LEFT JOIN
Find records with no matching entry
-- Customers who have never placed an order
SELECT c.name
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.order_id IS NULL;
Include all entities even without related data
-- All products with their sales (including products with zero sales)
SELECT p.product_name, COALESCE(SUM(oi.quantity), 0) AS units_sold
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.product_name
ORDER BY units_sold DESC;
Build complete reference datasets
-- All employees with their department info (including those not yet assigned)
SELECT e.name, e.title, COALESCE(d.department_name, 'Unassigned') AS department
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;
LEFT JOIN vs. Other Join Types
| Join Type | Left Table Rows | Right Table Rows | Unmatched Left | Unmatched Right |
|---|---|---|---|---|
| INNER JOIN | Only matched | Only matched | Excluded | Excluded |
| LEFT JOIN | All | Only matched | Included (NULLs for right) | Excluded |
| RIGHT JOIN | Only matched | All | Excluded | Included (NULLs for left) |
| FULL JOIN | All | All | Included | Included |
| CROSS JOIN | All | All | N/A (cartesian product) | N/A |
Common LEFT JOIN Mistakes
1. Filtering the right table in WHERE (converts to INNER JOIN)
-- BUG: WHERE condition on right table eliminates NULL rows
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.amount > 100; -- This removes customers with no orders!
-- FIX: Put the filter in the ON clause
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id AND o.amount > 100;
-- Now customers without qualifying orders still appear (with NULLs)
2. Duplicating left-table rows
A LEFT JOIN can produce more rows than the left table has if the right table has multiple matches:
-- If Alice has 2 orders, she appears twice in the result
-- To count customers (not order-rows), use COUNT(DISTINCT)
SELECT COUNT(DISTINCT c.id) AS customer_count
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
3. Using LEFT JOIN when INNER JOIN is correct
If you only care about records that have matches in both tables, use INNER JOIN. LEFT JOIN returns extra NULL rows you will just filter out anyway, wasting processing.
Which Style Should You Use?
Use LEFT JOIN (without OUTER). It is:
- More concise
- The industry standard
- Used in 95%+ of SQL codebases
- What every SQL tutorial teaches
The only reason to write LEFT OUTER JOIN is if your team's style guide requires it for explicitness, which is rare.
Summary
LEFT JOIN and LEFT OUTER JOIN are identical. Use LEFT JOIN for brevity. It returns all rows from the left table regardless of whether a match exists in the right table, filling NULLs where no match is found. Use it when you want to preserve all records from one table while optionally enriching them with data from another.
Saad Selim
The Skopx engineering and product team