SQL OUTER JOIN returns all records from both joined tables even there is no matching record found. There are three types of SQL OUTER JOIN:
- LEFT OUTER JOIN
- RIGHT OUTER,
- FULL OUTER JOIN
Employee table: employee id and name
Emp_id | Name |
100 | John |
110 | Mary |
111 | Smith |
112 | Bob |
113 | Jim |
114 | Joan |
115 | Jill |
Employee_hours_worked table: daily total hours each employee worked.
Emp_id | Date | Total_hours_worked |
1 | 2009-12-04 | 1 |
100 | 2010-01-12 | 3 |
110 | 2010-01-12 | 5 |
113 | 2010-01-13 | 2 |
111 | 2010-01-13 | 4 |
113 | 2010-01-13 | 6 |
110 | 2010-01-13 | 2 |
Left outer join preserve the table in the left side. Every row in the preserved table is presented in the result set with at least one result row.
select e.emp_id,e.name, w.date,w.total_hours_worked
from employee e
left join employee_hours_worked w
on e.emp_id = w.emp_id
emp_id | name | date | total_hours_worked |
100 | John | 1/12/2010 | 3 |
110 | Mary | 1/12/2010 | 5 |
110 | Mary | 1/13/2010 | 2 |
111 | Smith | 1/13/2010 | 4 |
112 | bob | ||
113 | Jim | 1/12/2010 | 2 |
113 | Jim | 1/13/2010 | 6 |
114 | Joan | ||
114 | Jill |
Put search predicate (filter) in the WHERE clause in a left outer join query will filter out the result set.
select e.emp_id,e.name, w.date,w.total_hours_worked
from employee e
left join employee_hours_worked w
on e.emp_id = w.emp_id
where w.total_hours_worked <=4
emp_id | name | date | total_hours_worked |
110 | Joan | 1/12/2010 | 3 |
110 | Mary | 1/13/2010 | 2 |
111 | Smith | 1/13/2010 | 4 |
113 | Jim | 1/12/2010 | 2 |
Put search predicate in the ON clause in a left outer join query will filter out only the matched records in the non preserved table.
select e.emp_id,e.name, w.date,w.total_hours_worked
from pcdb.employee e
left join pcdb.employee_hours_worked w
on e.emp_id = w.emp_id and w.total_hours_worked <=4
emp_id name date total_hours_worked
emp_id | name | date | total_hours_worked |
100 | john | 1/12/2010 | 3 |
110 | Mary | 1/13/2010 | 2 |
111 | Smith | 1/13/2010 | 4 |
112 | Bob | ||
113 | Jim | 1/12/2010 | 2 |
114 | Joan | ||
114 | Jill |
2 Right Outer Join
In Right outer join, the preserved table is on the right with is opposite to Left outer Join.
select e.emp_id,e.name, w.date,w.total_hours_worked
from pcdb.employee e
right outer join pcdb.employee_hours_worked w
on e.emp_id = w.emp_id
emp_id | name | date | total_hours_worked |
100 | John | 1/12/2010 | 3 |
110 | Mary | 1/12/2010 | 5 |
113 | Jim | 1/12/2010 | 2 |
111 | Smith | 1/13/2010 | 4 |
113 | Jim | 1/13/2010 | 2 |
110 | Mary | 1/13/2010 | 2 |
12/4/2009 | 1 |
Notice that the result set include the record that has not emp_id and name (last record).
3. Full Outer Join
Full Outer Join preserved both tables
select e.emp_id,e.name, w.date,w.total_hours_worked
from pcdb.employee e
full outer join pcdb.employee_hours_worked w
on e.emp_id = w.emp_id
emp_id | name | date | total_hours_worded |
100 | John | 1/12/2010 | 3 |
110 | Mary | 1/12/2010 | 5 |
110 | Mary | 1/13/2010 | 2 |
111 | Smith | 1/13/2010 | 4 |
112 | Bob | ||
113 | Jim | 1/12/2010 | 2 |
113 | Jim | 1/13/2010 | 6 |
114 | Joan | ||
115 | Jim | ||
12/4/2009 | 1 |
If a database server (like MySQL) dose not support full outer join, the query can be written with an union and a where clasue.
select e.emp_id,e.name, w.date,w.total_hours_worked
from pcdb.employee e
left outer join pcdb.employee_hours_worked w
on e.emp_id = w.emp_id
union
select e.emp_id,e.name, w.date,w.total_hours_worked
from pcdb.employee e
right outer join pcdb.employee_hours_worked w
on e.emp_id = w.emp_id
where e.emp_id is null
The where clause in the second query ,'where e.emp_id is null', keep all the the records that only exists in the right table, employee_hours_worked.
Reference
- SQL For Smarties by Joe Celko
- MySQL Cookbook by Paul DuBois
- Oracle Pl/SQL Programming by Steven Feuerstein and Bill Pribyl
No comments:
Post a Comment