An outer join[1] returns matching rows from two tables, plus
non-matching rows from one side of the join. Those non-matching rows appear with NULL values
for the columns coming from the table that did not match.
In modern SQL, outer joins are expressed with ANSI join keywords such as LEFT OUTER JOIN and
RIGHT OUTER JOIN. Oracle also supports a legacy syntax that uses the (+) operator in the
WHERE clause. This lesson focuses on reading and interpreting Oracle’s legacy form, while also showing
the ANSI equivalent so you can recognize both styles in real systems.
Outer Join Types and Meaning
Left outer join: keeps every row from the left table; unmatched rows from the right table become NULL.
Right outer join: keeps every row from the right table; unmatched rows from the left table become NULL.
Inner join: returns only rows that match on both sides; unmatched rows are excluded.
Oracle documentation often refers to “outer join” conceptually, but in ANSI SQL the left/right keywords are explicit
and easier to read. Oracle’s (+) syntax encodes left vs. right by the side where (+) appears.
Oracle (+) Syntax: Core Rule
In Oracle’s legacy syntax, the (+) marker is placed on the column(s) from the table that is
optional (the side that may fail to match).
Rule of thumb:
If table2.col(+) appears, then table2 is optional and the query behaves like a LEFT OUTER JOIN from table1 to table2.
If table1.col(+) appears, then table1 is optional and the query behaves like a RIGHT OUTER JOIN from table1 to table2.
SELECT col1, col2, ...
FROM table1, table2
WHERE table1.key = table2.key(+)
AND ...
Best practice: Prefer ANSI joins for new work. Oracle’s (+) syntax is widely seen in
legacy code, but ANSI joins are clearer and avoid several edge cases and restrictions.
Reading the diagram:
The SELECT list includes a column that becomes NULL for non-matching rows on the optional side of the join.
The FROM clause looks like a normal join in legacy syntax; the “outer” behavior is expressed in the WHERE clause.
The (+) marker identifies the optional table in the join predicate.
Functions such as NVL (or ANSI COALESCE) are commonly used to convert NULL values to something displayable, such as 0.
Rows that match on both sides appear normally and can be aggregated with SUM, COUNT, etc.
ANSI Example: Employees and Departments
Suppose you have:
employees: employee attributes including department_id
departments: department attributes including department_id and department_name
To list all employees (even those not assigned to a department), use a LEFT OUTER JOIN:
SELECT e.name, d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON e.department_id = d.department_id;
If an employee has no department, department_name appears as NULL.
Oracle (+) Example: PRODUCT and SALE_ITEM
The following query returns all products, including products that have no rows in SALE_ITEM. Notice the
(+) marker on the SALE_ITEM side of the predicate:
SELECT p.product_name,
SUM(NVL(si.sale_amount, 0)) AS dollars
FROM product p, sale_item si
WHERE p.product_id = si.product_id(+)
GROUP BY p.product_name
ORDER BY p.product_name;
What to notice in the query:
sale_item is optional because its join column is marked with (+).
Rows from product still appear even when no matching sale_item row exists.
NVL(si.sale_amount, 0) converts NULL to 0 so aggregation behaves predictably for display.
Outer Join vs Inner Join: Why Results Differ
Inner joins return only matched rows. That is appropriate when a missing match should exclude the record. Outer joins
are used when you want a “complete list” from one table and optional data from the other table.
For example, imagine:
customers contains all customers.
orders contains only recent orders.
An inner join lists only customers with recent orders. To include customers with no recent orders, use an outer join.
In ANSI form that is a LEFT OUTER JOIN. In Oracle (+) form, the (+) marker goes
on the orders side of the join predicate.
ANSI form:
SELECT c.lastname, c.firstname, o.order_id
FROM customers c
LEFT OUTER JOIN orders o
ON c.customer_id = o.customer_id
ORDER BY c.lastname, c.firstname;
Legacy Oracle (+) form:
SELECT c.lastname, c.firstname, o.order_id
FROM customers c, orders o
WHERE c.customer_id = o.customer_id(+)
ORDER BY c.lastname, c.firstname;
Oracle’s (+) operator can be understood as: “if no match exists, Oracle supplies a placeholder row on the
optional side with NULL values.” The placeholder row is not stored in any table; it exists only to form
the result set.
Inner Join vs Outer Join Quiz
Click the quiz link below to test your understanding of inner joins versus outer joins.
Inner Join Outer Join - Quiz
[1]Outer join: A join that returns matched rows plus non-matching rows from one side, filling the other side’s columns with NULL.
Left outer join: Keeps every row from the left table; unmatched rows from the right table appear with NULL values.
Right outer join: Keeps every row from the right table; unmatched rows from the left table appear with NULL values.
Inner join: Returns only rows that match on both sides of the join condition.