Vous êtes sur la page 1sur 12

Sample tables

All subsequent explanations on join types in this article make use of the following two
tables. The rows in these tables serve to illustrate the effect of different types of joins and
join-predicates. In the following tables the DepartmentID column of the Department
table which can be designated as Department.DepartmentID! is the primary key" while
Employee.DepartmentID is a foreign key.
#mployee Table
LastName DepartmentID
$afferty %&
'ones %%
(teinberg %%
$obinson %)
(mith %)
'ohn
NULL
*epartment Table
DepartmentID DepartmentName
%& (ales
%% #ngineering
%) +lerical
%, -arketing
.ote/ The 0-arketing0 *epartment currently has no listed employees. Also" employee
0'ohn0 has not been assigned to any *epartment yet.
(cript to create the tables
CREATE TABLE employee (
LastName varchar(25)
DepartmentID !nt
)
CREATE TABLE "epartment (
DepartmentID !nt UNI#UE
DepartmentName varchar(25)
)
ALTER TABLE employee
ADD C$N%TRAINT &'(employee("ept
)$REI*N +E, (DepartmentID)
RE)ERENCE% "epartment(DepartmentID)-
(cript to add data to the tables
IN%ERT INT$ "epartment .ALUE% (/01%ales1)-
IN%ERT INT$ "epartment .ALUE% (//1En2!neer!n21)-
IN%ERT INT$ "epartment .ALUE% (/31Cler!cal1)-
IN%ERT INT$ "epartment .ALUE% (/514ar'et!n21)-
IN%ERT INT$ employee .ALUE% (1Ra&&erty1/0)-
IN%ERT INT$ employee .ALUE% (15ones1//)-
IN%ERT INT$ employee .ALUE% (1%te!n6er21//)-
IN%ERT INT$ employee .ALUE% (1Ro6!nson1/3)-
IN%ERT INT$ employee .ALUE% (1%m!th1/3)-
IN%ERT INT$ employee .ALUE% (15ohn1NULL)-
[edit] Inner join
An inner join is the most common join operation used in applications and can be
regarded as the default join-type. Inner join creates a new result table by combining
column values of two tables A and 1! based upon the join-predicate. The query
compares each row of A with each row of 1 to find all pairs of rows which satisfy the
join-predicate. 2hen the join-predicate is satisfied" column values for each matched pair
of rows of A and 1 are combined into a result row. The result of the join can be defined as
the outcome of first taking the +artesian product or cross-join! of all records in the tables
combining every record in table A with every record in table 1!3then return all records
which satisfy the join predicate. Actual (45 implementations normally use other
approaches like a hash join or a sort-merge join where possible" since computing the
+artesian product is very inefficient.
(45 specifies two different syntactical ways to express joins/ 0explicit join notation0 and
0implicit join notation0.
The 0explicit join notation0 uses the 5$IN keyword to specify the table to join" and the $N
keyword to specify the predicates for the join" as in the following example/

%ELECT 7
)R$4 employee INNER 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
The 0implicit join notation0 simply lists the tables for joining in the )R$4 clause of the
%ELECT statement!" using commas to separate them. Thus" it specifies a cross-join" and
the 9:ERE clause may apply additional filter-predicates which function comparably to
the join-predicates in the explicit notation!.
The following example shows a query which is equivalent to the one from the previous
example" but this time written using the implicit join notation/
%ELECT 7
)R$4 employee "epartment
9:ERE employee.DepartmentID 8 "epartment.DepartmentID-
The queries given in the examples above will join the #mployee and *epartment tables
using the *epartmentI* column of both tables. 2here the *epartmentI* of these tables
match i.e. the join-predicate is satisfied!" the query will combine the LastName"
DepartmentID and DepartmentName columns from the two tables into a result row.
2here the *epartmentI* does not match" no result row is generated.
Thus the result of the execution of either of the two queries above will be/
Employee.LastN
ame
Employee.Departm
entID
Department.Departmen
tName
Department.Departm
entID
$obinson %) +lerical %)
'ones %% #ngineering %%
(mith %) +lerical %)
(teinberg %% #ngineering %%
$afferty %& (ales %&
Note: 6rogrammers should take special care when joining tables on columns that can
contain .755 values" since .755 will never match any other value or even .755
itself!" unless the join condition explicitly uses the I% NULL or I% N$T NULL predicates.
.otice that the employee 0'ohn0 and the department 0-arketing0 do not appear in the
query execution results. .either of these has any matching records in the respective other
table/ 0'ohn0 has no associated department" and no employee has the department I* %,.
Thus" no information on 'ohn or on -arketing appears in the joined table. *epending on
the desired results" this behavior may be a subtle bug. 8uter joins may be used to avoid it.
8ne can further classify inner joins as equi-joins" as natural joins" or as cross-joins.
[edit] Equi-join
An equi-join" also known as an equijoin" is a specific type of comparator-based join" or
theta join" that uses only equality comparisons in the join-predicate. 7sing other
comparison operators such as ;! disqualifies a join as an equi-join. The query shown
above has already provided an example of an equi-join/
%ELECT 7
)R$4 employee
E#UI 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
(45 provides an optional shorthand notation for expressing equi-joins" by way of the
U%IN* construct/
%ELECT 7
)R$4 employee
INNER 5$IN "epartment
U%IN* (DepartmentID)-
The U%IN* construct is more than mere syntactic sugar" however" since the result set
differs from the result set of the version with the explicit predicate. (pecifically" any
columns mentioned in the U%IN* list will appear only once" with an unqualified name"
rather than once for each table in the join. In the above case" there will be a single
DepartmentID column and no employee.DepartmentID or
"epartment.DepartmentID.
The U%IN* clause is not supported by (45 (erver 9::, and (ybase.
[edit] Natural join
A natural join offers a further speciali;ation of equi-joins. The join predicate arises
implicitly by comparing all columns in both tables that have the same column-name in
the joined tables. The resulting joined table contains only one column for each pair of
equally-named columns.
The above sample query for inner joins can be expressed as a natural join in the following
way/
%ELECT 7
)R$4 employee NATURAL 5$IN "epartment-
As with the explicit U%IN* clause" only one *epartmentI* column occurs in the joined
table" with no qualifier/
DepartmentID Employee.LastName Department.DepartmentName
%) (mith +lerical
%% 'ones #ngineering
%) $obinson +lerical
%% (teinberg #ngineering
%& $afferty (ales
[edit] Cross join
#xample of an explicit cross join/
%ELECT 7
)R$4 employee CR$%% 5$IN "epartment-
#xample of an implicit cross join/
%ELECT 7
)R$4 employee "epartment-
Employee.LastN
ame
Employee.Departm
entID
Department.Departmen
tName
Department.Departm
entID
$afferty %& (ales %&
'ones %% (ales %&
(teinberg %% (ales %&
(mith %) (ales %&
$obinson %) (ales %&
'ohn
NULL
(ales %&
$afferty %& #ngineering %%
'ones %% #ngineering %%
(teinberg %% #ngineering %%
(mith %) #ngineering %%
$obinson %) #ngineering %%
'ohn
NULL
#ngineering %%
$afferty %& +lerical %)
'ones %% +lerical %)
(teinberg %% +lerical %)
(mith %) +lerical %)
$obinson %) +lerical %)
'ohn
NULL
+lerical %)
$afferty %& -arketing %,
'ones %% -arketing %,
(teinberg %% -arketing %,
(mith %) -arketing %,
$obinson %) -arketing %,
'ohn
NULL
-arketing %,
The cross join does not apply any predicate to filter records from the joined table.
6rogrammers can further filter the results of a cross join by using a 9:ERE clause.
[edit] Outer joins
An outer join does not require each record in the two joined tables to have a matching
record. The joined table retains each record3even if no other matching record exists.
8uter joins subdivide further into left outer joins" right outer joins" and full outer joins"
depending on which tables! one retains the rows from left" right" or both!.
In this case left and right refer to the two sides of the 5$IN keyword.!
.o implicit join-notation for outer joins exists in standard (45.
[edit] Let outer join
The result of a left outer join or simply let join! for table A and 1 always contains all
records of the 0left0 table A!" even if the join-condition does not find any matching
record in the 0right0 table 1!. This means that if the $N clause matches : ;ero! records
in 1" the join will still return a row in the result3but with .755 in each column from 1.
This means that a let outer join returns all the values from the left table" plus matched
values from the right table or .755 in case of no matching join predicate!. If the right
table returns one row and the left table returns more than one matching row for it" the
values in the right table will be repeated for each distinct row on the left table.
<or example" this allows us to find an employee=s department" but still shows the
employees! even when they have not been assigned to a department contrary to the
inner-join example above" where unassigned employees are excluded from the result!.
#xample of a left outer join" with the additional result row italici;ed/
%ELECT 7
)R$4 employee LE)T $UTER 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
Employee.LastN
ame
Employee.Departm
entID
Department.Departmen
tName
Department.Departm
entID
'ones %% #ngineering %%
$afferty %& (ales %&
$obinson %) +lerical %)
(mith %) +lerical %)
John
NULL NULL NULL
(teinberg %% #ngineering %%
8racle supports the alternate syntax/
%ELECT 7 )R$4 employee "epartment 9:ERE employee.DepartmentID 8
"epartment.DepartmentID(<)
[edit] !i"#t outer joins
A ri"#t outer join or ri"#t join! closely resembles a left outer join" except with the
treatment of the tables reversed. #very row from the 0right0 table 1! will appear in the
joined table at least once. If no matching row from the 0left0 table A! exists" .755 will
appear in columns from A for those records that have no match in 1.
A right outer join returns all the values from the right table and matched values from the
left table .755 in case of no matching join predicate!.
<or example" this allows us to find each employee and his or her department" but still
show departments that have no employees.
#xample right outer join" with the additional result row italici;ed/
%ELECT 7
)R$4 employee RI*:T $UTER 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
Employee.LastN
ame
Employee.Departm
entID
Department.Departmen
tName
Department.Departm
entID
(mith %) +lerical %)
'ones %% #ngineering %%
$obinson %) +lerical %)
(teinberg %% #ngineering %%
$afferty %& (ales %&
NULL NULL
Marketing 35
In practice" explicit right outer joins are rarely used" since they can always be replaced
with left outer joins with the table order switched! and provide no additional
functionality. The result above is produced also with a left outer join/
%ELECT 7
)R$4 "epartment LE)T $UTER 5$IN employee
$N employee.DepartmentID 8 "epartment.DepartmentID-
[edit] $ull outer join
+onceptually" a ull outer join combines the effect of applying both left and right outer
joins. 2here records in the <755 87T#$ '8I.ed tables do not match" the result set will
have .755 values for every column of the table that lacks a matching row. <or those
records that do match" a single row will be produced in the result set containing fields
populated from both tables!.
<or example" this allows us to see each employee who is in a department and each
department that has an employee" but also see each employee who is not part of a
department and each department which doesn=t have an employee.
#xample full outer join/
%ELECT 7
)R$4 employee
)ULL $UTER 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
Employee.LastN
ame
Employee.Departm
entID
Department.Departmen
tName
Department.Departm
entID
(mith %) +lerical %)
'ones %% #ngineering %%
$obinson %) +lerical %)
John
NULL NULL NULL
(teinberg %% #ngineering %%
$afferty %& (ales %&
NULL NULL
Marketing 35
(ome database systems like -y(45! do not support this functionality directly" but they
can emulate it through the use of left and right outer joins and unions. The same example
can appear as follows/
%ELECT 7
)R$4 employee
LE)T 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID
UNI$N
%ELECT 7
)R$4 employee
RI*:T 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
(45ite does not support right join" so outer join can be emulated as follows/
%ELECT employee.7 "epartment.7
)R$4 employee
LE)T 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID
UNI$N ALL
%ELECT employee.7 "epartment.7
)R$4 "epartment
LE)T 5$IN employee
$N employee.DepartmentID 8 "epartment.DepartmentID
9:ERE employee.DepartmentID I% NULL-
[edit] Sel-join
A self-join is joining a table to itself.
>9?
This is best illustrated by an example.
[edit] E%ample
A query to find all pairings of two employees in the same country is desired. If you had
two separate tables for employees and a query which requested employees in the first
table having the same country as employees in the second table" you could use a normal
join operation to find the answer table. @owever" all the employee information is
contained within a single large table.
>%?
+onsidering a modified Employee table such as the following/
#mployee Table
EmployeeID LastName Country DepartmentID
&9% $afferty Australia %&
&9) 'ones Australia %%
&), (teinberg Australia %%
9:& $obinson 7nited (tates %)
%:, (mith Aermany %)
%:B 'ohn Aermany
NULL
An example solution query could be as follows/
%ELECT ).EmployeeID ).LastName %.EmployeeID %.LastName ).Co=ntry
)R$4 Employee ) Employee %
9:ERE ).Co=ntry 8 %.Co=ntry
AND ).EmployeeID ; %.EmployeeID
$RDER B, ).EmployeeID %.EmployeeID-
2hich results in the following table being generated.
#mployee Table after (elf-join by +ountry
EmployeeID LastName EmployeeID LastName Country
&9% $afferty &9) 'ones Australia
&9% $afferty &), (teinberg Australia
&9) 'ones &), (teinberg Australia
%:, (mith %:B 'ohn Aermany
<or this example" note that/
) and % are aliases for the first and second copies of the employee table.
The condition ).Co=ntry 8 %.Co=ntry excludes pairings between employees in
different countries. The example question only wanted pairs of employees in the
same country.
The condition ).EmployeeID ; %.EmployeeID excludes pairings where the
EmployeeIDs are the same.
).EmployeeID ; %.EmployeeID also excludes duplicate pairings. 2ithout it" the
following less useful table would be generated the table below displays only the
0Aermany0 portion of the result!/
EmployeeID LastName EmployeeID LastName Country
%:, (mith %:, (mith Aermany
%:, (mith %:B 'ohn Aermany
%:B 'ohn %:, (mith Aermany
%:B 'ohn %:B 'ohn Aermany
8nly one of the two middle pairings is needed to satisfy the original question" and the
topmost and bottommost are of no interest at all in this example.
[edit] &er"e ro's
To be able to do a select so as to merge multiple rows into & row / 0groupCconcat
notation0.
-y(45 uses the 2ro=p(concat keyword to achieve that goal" and 6ostgre(45 D.: has
the str!n2(a22 function. Eersions before D.: required the use of something like
array(to(str!n2(array(a22(val=e)1 1)
or the creation of an aggregate function.
7sing the #mployee Table/
LastName DepartmentID
$afferty %&
'ones %%
(teinberg %%
$obinson %)
(mith %)
'ohn
NULL
to achieve the following results Table
DepartmentID LastNames
NULL
'ohn
%& $afferty
%% 'ones" (teinberg
%) $obinson" (mith
[edit] &yS(L
%ELECT DepartmentID 2ro=p(concat(LastName) A% LastNames
)R$4 employee
*R$U> B, DepartmentID-
[edit] )ost"reS(L
<irst the function CgroupCconcat and aggregate groupCconcat need to be created before
that query can be possible.
CREATE $R RE>LACE )UNCTI$N (2ro=p(concat(te?t te?t)
RETURN% te?t A% @@
%ELECT CA%E
9:EN @2 I% NULL T:EN @0
9:EN @0 I% NULL T:EN @2
EL%E @0 operator(p2(catalo2.AA) 1 1 operator(p2(catalo2.AA) @2
END
@@ I44UTABLE LAN*UA*E %#L-

errorBB 5$IN %#L
CREATE A**RE*ATE 2ro=p(concat (
BA%ET,>E 8 te?t
%)UNC 8 (2ro=p(concat
%T,>E 8 te?t
)-

%ELECT DepartmentID 2ro=p(concat(LastName) A% LastNames
)R$4 employee
*R$U> B, DepartmentID-
As for version D.:/
%ELECT DepartmentID str!n2(a22(LastName 1 1) A% LastNames
)R$4 employee
*R$U> B, DepartmentID-
[edit] *lternati+es
The effect of outer joins can also be obtained using correlated subqueries. <or example
%ELECT employee.LastName employee.DepartmentID
"epartment.DepartmentName
)R$4 employee LE)T $UTER 5$IN "epartment
$N employee.DepartmentID 8 "epartment.DepartmentID-
can also be written as
%ELECT employee.LastName employee.DepartmentID
(%ELECT "epartment.DepartmentName
)R$4 "epartment
9:ERE "epartment.DepartmentID 8 employee.DepartmentID ) A%
DepartmentName
)R$4 employee-
[edit] Implementation
-uch work in database-systems has aimed at efficient implementation of joins" because
relational systems commonly call for joins" yet face difficulties in optimising their
efficient execution. The problem arises because inner joins operate both commutatively
and associatively. In practice" this means that the user merely supplies the list of tables
for joining and the join conditions to use" and the database system has the task of
determining the most efficient way to perform the operation. A query optimi;er
determines how to execute a query containing joins. A query optimi;er has two basic
freedoms/
&. ,oin order/ 1ecause joins function commutatively and associatively" the order in
which the system joins tables does not change the final result-set of the query.
@owever" join-order does have an enormous impact on the cost of the join
operation" so choosing the best join order becomes very important.
9. ,oin met#od/ Aiven two tables and a join condition" multiple algorithms can
produce the result-set of the join. 2hich algorithm runs most efficiently depends
on the si;es of the input tables" the number of rows from each table that match the
join condition" and the operations required by the rest of the query.
-any join-algorithms treat their inputs differently. 8ne can refer to the inputs to a join as
the 0outer0 and 0inner0 join operands" or 0left0 and 0right0" respectively. In the case of
nested loops" for example" the database system will scan the entire inner relation for each
row of the outer relation.
8ne can classify query-plans involving joins as follows/
>)?
left-deep
using a base table rather than another join! as the inner operand of each join in
the plan
right-deep
using a base table as the outer operand of each join in the plan
bushy
neither left-deep nor right-deepF both inputs to a join may themselves result from
joins
These names derive from the appearance of the query plan if drawn as a tree" with the
outer join relation on the left and the inner relation on the right as convention dictates!.
[edit] ,oin al"orit#ms
Three fundamental algorithms exist for performing a join operation/ .ested loop join"
(ort-merge join and @ash join.

Vous aimerez peut-être aussi