Sunteți pe pagina 1din 1

Chapter 3: Selecting 87

SELECT parent.parent_key,
parent.data_1,
child.child_key,
child.parent_key
FROM parent LEFT OUTER JOIN child ON parent.parent_key = child.parent_key
AND parent.data_1 = 'x'
ORDER BY parent.parent_key,
child.child_key;
In this case the result set is exactly the same as it was before:
parent. parent. child. child.
parent_key data_1 child_key parent_key
========== ======= ========= ==========
1 x 4 1 -- parent and child
1 x 5 1 -- parent and child
1 x 6 1 -- parent and child
2 x NULL NULL -- parent with no children
3 y NULL NULL -- parent with no children
The fact that a row with parent.data_1 = 'y' is included even though the ON con-
dition specified only rows with 'x' were to be included often comes as a surprise.
Its the way an OUTER JOIN works, and its the way its supposed to work, but
it is often not exactly what you want.

Tip: Be very careful what you code in the ON condition of an OUTER JOIN. A
good rule of thumb is to only code conditions that affect how rows from both
tables are joined, not conditions affecting only one or the other table. If you want
to eliminate rows in one or the other table before the OUTER JOIN is applied,
use a derived table or a view.

3.5 Derived Tables


A derived table is a mechanism where you can code an entire subquery inside a
FROM clause, and have the result set from that subquery treated like any other
table term in the FROM clause.
<derived_table> ::= <subquery>
[ AS ] <correlation_name>
[ <derived_column_name_list> ]
<derived_column_name_list> ::= "(" <alias_name_list> ")"
<alias_name_list> ::= <alias_name> { "," <alias_name> }
<alias_name> ::= <identifier>
In the previous example, a LEFT OUTER JOIN was written using an ON condi-
tion that didnt satisfy the requirements, (only parent rows with parent.data_1 =
'x' were to be included in the result set). The problem was that a row with par-
ent.data_1 = 'y' was included because of the way OUTER JOIN operators work.
Heres how a derived table can be used to solve that problem by eliminating the
unwanted rows before the LEFT OUTER JOIN is applied:
SELECT parent.parent_key,
parent.data_1,
child.child_key,
child.parent_key
FROM ( SELECT *
FROM parent
WHERE parent.data_1 = 'x' ) AS parent

S-ar putea să vă placă și