|
December 2004 Technical Tip – Outer Joins, ON, WHERE and
AND
In this article I will introduce the use of outer joins in SQL,
with particular emphasis on the placement of the and operator, in
conjunction with the on and where clauses. I will refer to
the following tables in this article. The EMPL tables contains employee
data and the THISPP table contains the hours worked by each employee this
pay period:
mysql> select * from empl;
+------+--------+--------+------+--------+------+------------+
| enum | lname | fname | dept | rate | type | hire |
+------+--------+--------+------+--------+------+------------+
| 211 | DAYLEY | BRIAN | A | 6.00 | H | 1991-07-26 |
| 270 | DAYLEY | CINDY | B | 300.00 | S | 1990-04-11 |
| 601 | STEELE | DOUG | A | 5.00 | H | 1992-06-30 |
| 719 | ALFORD | BRIAN | B | 4.50 | H | 1992-12-31 |
| 828 | GOYAK | DEBBIE | A | 320.00 | S | 1989-11-08 |
| 857 | ALFORD | MARK | B | 5.00 | H | 1992-12-27 |
+------+--------+--------+------+--------+------+------------+
mysql> select * from thispp;
+------+-------+
| enum | hours |
+------+-------+
| 601 | 30.00 |
| 828 | 42.00 |
| 270 | 35.00 |
| 211 | 25.00 |
| 719 | 30.00 |
+------+-------+
|
Note that employee 857 did not work this pay period and therefore is
not found in the THISPP table. This is critical to the following
discussion.
The traditional join used in SQL is more correctly known as an inner
join. Recall that in this type of join, a where clause is used
to indicate rows to be returned based upon values which the base tables
have in common. For example:
mysql> select e.enum, e.lname, e.fname, e.dept, e.rate, e.type, p.hours
-> from empl e, thispp p
-> where e.enum = p.enum;
+------+--------+--------+------+--------+------+-------+
| enum | lname | fname | dept | rate | type | hours |
+------+--------+--------+------+--------+------+-------+
| 601 | STEELE | DOUG | A | 5.00 | H | 30.00 |
| 828 | GOYAK | DEBBIE | A | 320.00 | S | 42.00 |
| 270 | DAYLEY | CINDY | B | 300.00 | S | 35.00 |
| 211 | DAYLEY | BRIAN | A | 6.00 | H | 25.00 |
| 719 | ALFORD | BRIAN | B | 4.50 | H | 30.00 |
+------+--------+--------+------+--------+------+-------+
|
An outer join returns unmatched rows as well. In a full outer
join, all rows from all tables – matched as well as unmatched – are
returned at least once. In a left outer join or right outer
join all rows from the designated table are returned at least once.
When an outer join is used, the on clause is used to indicate which
rows are returned from the join. For example:
mysql> select e.enum, e.lname, e.fname, e.dept, e.rate, e.type, p.hours
-> from empl e left outer join thispp p on e.enum = p.enum;
+------+--------+--------+------+--------+------+-------+
| enum | lname | fname | dept | rate | type | hours |
+------+--------+--------+------+--------+------+-------+
| 211 | DAYLEY | BRIAN | A | 6.00 | H | 25.00 |
| 270 | DAYLEY | CINDY | B | 300.00 | S | 35.00 |
| 601 | STEELE | DOUG | A | 5.00 | H | 30.00 |
| 719 | ALFORD | BRIAN | B | 4.50 | H | 30.00 |
| 828 | GOYAK | DEBBIE | A | 320.00 | S | 42.00 |
| 857 | ALFORD | MARK | B | 5.00 | H | NULL |
+------+--------+--------+------+--------+------+-------+
|
The where clause can be used to further reduce the rows returned
by the query. For example:
mysql> select e.enum, e.lname, e.fname, e.dept, e.rate, e.type, p.hours
-> from empl e left outer join thispp p on e.enum = p.enum
-> where e.type = 'H';
+------+--------+-------+------+------+------+-------+
| enum | lname | fname | dept | rate | type | hours |
+------+--------+-------+------+------+------+-------+
| 211 | DAYLEY | BRIAN | A | 6.00 | H | 25.00 |
| 601 | STEELE | DOUG | A | 5.00 | H | 30.00 |
| 719 | ALFORD | BRIAN | B | 4.50 | H | 30.00 |
| 857 | ALFORD | MARK | B | 5.00 | H | NULL |
+------+--------+-------+------+------+------+-------+
|
The and operator can be used with the on clause as well
as with the where clause. Its placement is signficant: the
key point to remember is that the where clause subsets the
individual detail rows before the outer join is performed. The on
clause then specifies how the remaining rows are to be selected for
output. In the following queries we add the constraint E.DEPT =
'B'. The two queries differ only in their placement of the and, and
yet the results are significantly different:
mysql> select e.enum, e.lname, e.fname, e.dept, e.rate, e.type, p.hours
-> from empl e left outer join thispp p on e.enum = p.enum and e.dept = 'B'
-> where e.type = 'H';
+------+--------+-------+------+------+------+-------+
| enum | lname | fname | dept | rate | type | hours |
+------+--------+-------+------+------+------+-------+
| 211 | DAYLEY | BRIAN | A | 6.00 | H | NULL |
| 601 | STEELE | DOUG | A | 5.00 | H | NULL |
| 719 | ALFORD | BRIAN | B | 4.50 | H | 30.00 |
| 857 | ALFORD | MARK | B | 5.00 | H | NULL |
+------+--------+-------+------+------+------+-------+
mysql> select e.enum, e.lname, e.fname, e.dept, e.rate, e.type, p.hours
-> from empl e left outer join thispp p on e.enum = p.enum
-> where e.type = 'H' and e.dept = 'B';
+------+--------+-------+------+------+------+-------+
| enum | lname | fname | dept | rate | type | hours |
+------+--------+-------+------+------+------+-------+
| 719 | ALFORD | BRIAN | B | 4.50 | H | 30.00 |
| 857 | ALFORD | MARK | B | 5.00 | H | NULL |
+------+--------+-------+------+------+------+-------+
|
I used MySQL for the examples in this article. For information on
getting started with MySQL, see our January 2004
article.
Want to know more about SQL? Give us a call! You can count on Caliber
Data Training for top quality mainframe and/or internet programming
education.
Go to the articles index. Written
by Bill Qualls. Copyright © 2004 by Caliber Data Training
800.938.1222 |