(+) is an Oracle specific function[1].
Let's go with the old and trivial example of the employees and the departments in a company, before we dive any deeper. It seems to work for everyone else, so it should work here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SELECT | |
last_name, | |
department_name | |
FROM | |
employees e, | |
departments d | |
WHERE | |
e.department_id = d.department_id(+); | |
-- changed to | |
SELECT | |
last_name, | |
department_name | |
FROM | |
employees e | |
LEFT OUTER JOIN | |
departments d | |
ON | |
e.department_id = d.department_id; |
The example comes straight from [3]. It will show NULL for the department values for all employees that are not assigned to a department. Wikipedia has a nice article on the behaviour of outer joins.[4]
Multiple Outer Join
This is an example of how you could use left join multiple times.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- show all employees, including their departments, | |
-- contact information, jobtitle, salary etc. | |
SELECT | |
e.last_name, | |
e.salary, | |
e.scale, | |
d.department_name, | |
c.description, | |
j.title, | |
j.stdsalary | |
FROM | |
employees e, | |
departments d, | |
contacts c, | |
jobs j | |
WHERE | |
e.department_id = d.department_id(+) | |
AND d.deleted(+) = false | |
AND e.id = c.id(+) | |
AND e.jobtitle = j.title(+) | |
AND e.left_company = false | |
-- changed to | |
SELECT | |
e.last_name, | |
e.salary, | |
e.scale, | |
d.department_name, | |
c.description, | |
j.title, | |
j.stdsalary | |
FROM | |
employees e | |
LEFT OUTER JOIN | |
departments d | |
ON | |
e.department_id = d.department_id | |
AND d.deleted = false | |
LEFT OUTER JOIN | |
contacts c | |
ON | |
e.id = c.id | |
LEFT OUTER JOIN | |
jobs j | |
ON | |
e.jobtitle = j.title | |
WHERE | |
e.left_company = false |
This won't work
You can write conditions in the "ON" clause, however, these conditions must be related to the SLAVE table. The following, for example, will not work.[2]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SELECT | |
last_name, | |
department_name | |
FROM | |
employees e | |
LEFT OUTER JOIN | |
departments d | |
ON | |
e.department_id = d.department_id | |
AND e.left_company = false; |
The solution here is to move the offending condition into the WHERE clause.
Odd one out
The example below, I encountered, is a bit odd, as it is not really an outer join between tables. It is used here to prevent having to write the 'or is null' part.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- provides all employee that are not higher management | |
-- includes employees without a job title | |
SELECT * FROM employees | |
WHERE jobtitle (+) not in ('manager', 'department head', 'president') | |
-- changed to | |
select * from employees | |
where jobtitle not in ('manager', 'department head', 'president') | |
or jobtitle is null |
References
- [1] Oracle (+)
- http://docs.oracle.com/cd/B28359_01/server.111/b28286/queries006.htm
- [2] The ON condition
- http://www.oreillynet.com/pub/a/network/2002/10/01/whatsinacondition.html>
- [3] Example Oracle Left Outer Join
- http://www.dba-oracle.com/tips_oracle_left_outer_join.htm
- [4] Wikipedia JOIN SQL
- http://en.wikipedia.org/wiki/Join_%28SQL%29
- Outer joins in Oracle
- https://blogs.oracle.com/optimizer/entry/outerjoins_in_oracle
- A Visual Explanation of SQL Joins
- http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html