any remaining columns from <replaceable>T2</replaceable>.
</para>
<para>
<indexterm>
<primary>join</primary>
<secondary>natural</secondary>
</indexterm>
<indexterm>
<primary>natural join</primary>
</indexterm>
Finally, <literal>NATURAL</literal> is a shorthand form of
<literal>USING</literal>: it forms a <literal>USING</literal> list
consisting of all column names that appear in both
input tables. As with <literal>USING</literal>, these columns appear
only once in the output table. If there are no common
column names, <literal>NATURAL JOIN</literal> behaves like
<literal>CROSS JOIN</literal>.
</para>
<note>
<para>
<literal>USING</literal> is reasonably safe from column changes
in the joined relations since only the listed columns
are combined. <literal>NATURAL</literal> is considerably more risky since
any schema changes to either relation that cause a new matching
column name to be present will cause the join to combine that new
column as well.
</para>
</note>
</listitem>
</varlistentry>
</variablelist>
<para>
To put this together, assume we have tables <literal>t1</literal>:
<programlisting>
num | name
-----+------
1 | a
2 | b
3 | c
</programlisting>
and <literal>t2</literal>:
<programlisting>
num | value
-----+-------
1 | xxx
3 | yyy
5 | zzz
</programlisting>
then we get the following results for the various joins:
<screen>
<prompt>=></prompt> <userinput>SELECT * FROM t1 CROSS JOIN t2;</userinput>
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)
<prompt>=></prompt> <userinput>SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</userinput>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(2 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 INNER JOIN t2 USING (num);</userinput>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 NATURAL INNER JOIN t2;</userinput>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</userinput>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
(3 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 USING (num);</userinput>
num | name | value
-----+------+-------
1 | a | xxx
2 | b |
3 | c | yyy
(3 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</userinput>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
| | 5 | zzz
(3 rows)
<prompt>=></prompt> <userinput>SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</userinput>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
| | 5 | zzz
(4 rows)
</screen>
</para>
<para>
The join condition specified with <literal>ON</literal> 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:
<screen>
<prompt>=></prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</userinput>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | |
(3 rows)
</screen>
Notice that placing