| PostgreSQL Reference Manual - Volume 1 - SQL Language Reference by The PostgreSQL Global Development Group Paperback (6"x9"), 716 pages ISBN 0954612027 RRP £32.00 ($49.95) Sales of this book support the PostgreSQL project! Get a printed copy>>> |
5.2.1.1 Joined Tables
A joined table is a table derived from two other (real or derived) tables according to the rules of the particular join type. Inner, outer, and cross-joins are available.
Join Types:
- Cross join
-
T1 CROSS JOIN T2
For each combination of rows from T1 and T2, the derived table will contain a row consisting of all columns in T1 followed by all columns in T2. If the tables have N and M rows respectively, the joined table will have N * M rows.FROM T1 CROSS JOIN T2is equivalent toFROM T1, T2. It is also equivalent toFROM T1 INNER JOIN T2 ON TRUE(see below). - Qualified joins
-
T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 USING ( join column list ) T1 NATURAL { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2The wordsINNERandOUTERare optional in all forms.INNERis the default;LEFT,RIGHT, andFULLimply an outer join. The join condition is specified in theONorUSINGclause, or implicitly by the wordNATURAL. The join condition determines which rows from the two source tables are considered to “match”, as explained in detail below. TheONclause is the most general kind of join condition: it takes a Boolean value expression of the same kind as is used in aWHEREclause. A pair of rows from T1 and T2 match if theONexpression evaluates to true for them.USINGis a shorthand notation: it takes a comma-separated list of column names, which the joined tables must have in common, and forms a join condition specifying equality of each of these pairs of columns. Furthermore, the output of aJOIN USINGhas one column for each of the equated pairs of input columns, followed by all of the other columns from each table. Thus,USING (a, b, c)is equivalent toON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c)with the exception that ifONis used there will be two columnsa,b, andcin the result, whereas withUSINGthere will be only one of each. Finally,NATURALis a shorthand form ofUSING: it forms aUSINGlist consisting of exactly those column names that appear in both input tables. As withUSING, these columns appear only once in the output table. The possible types of qualified join are:INNER JOIN- For each row R1 of T1, the joined table has a row for each row in T2 that satisfies the join condition with R1.
LEFT OUTER JOIN- First, an inner join is performed. Then, for each row in T1 that does not satisfy the join condition with any row in T2, a joined row is added with null values in columns of T2. Thus, the joined table unconditionally has at least one row for each row in T1.
RIGHT OUTER JOIN- First, an inner join is performed. Then, for each row in T2 that does not satisfy the join condition with any row in T1, a joined row is added with null values in columns of T1. This is the converse of a left join: the result table will unconditionally have a row for each row in T2.
FULL OUTER JOIN- First, an inner join is performed. Then, for each row in T1 that does not satisfy the join condition with any row in T2, a joined row is added with null values in columns of T2. Also, for each row of T2 that does not satisfy the join condition with any row in T1, a joined row with null values in the columns of T1 is added.
Joins of all types can be chained together or nested: either or
both of T1 and
T2 may be joined tables. Parentheses
may be used around JOIN clauses to control the join
order. In the absence of parentheses, JOIN clauses
nest left-to-right.
To put this together, assume we have tables t1
num | name -----+------ 1 | a 2 | b 3 | c
and t2
num | value -----+------- 1 | xxx 3 | yyy 5 | zzz
then we get the following results for the various joins:
=> SELECT * FROM t1 CROSS JOIN t2;
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
1 | a | 3 | yyy
1 | a | 5 | zzz
2 | b | 1 | xxx
2 | b | 3 | yyy
2 | b | 5 | zzz
3 | c | 1 | xxx
3 | c | 3 | yyy
3 | c | 5 | zzz
(9 rows)
=> SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(2 rows)
=> SELECT * FROM t1 INNER JOIN t2 USING (num);
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
=> SELECT * FROM t1 NATURAL INNER JOIN t2;
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
(3 rows)
=> SELECT * FROM t1 LEFT JOIN t2 USING (num);
num | name | value
-----+------+-------
1 | a | xxx
2 | b |
3 | c | yyy
(3 rows)
=> SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
| | 5 | zzz
(3 rows)
=> SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
| | 5 | zzz
(4 rows)
The join condition specified with ON can also contain
conditions that do not relate directly to the join. This can
prove useful for some queries but needs to be thought out
carefully. For example:
=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx'; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 2 | b | | 3 | c | | (3 rows)
| ISBN 0954612027 | PostgreSQL Reference Manual - Volume 1 - SQL Language Reference | See the print edition |