Home Explore Blog CI



postgresql

6th chunk of `doc/src/sgml/queries.sgml`
5cf6184eddbaa9007223cc3f6ad8975e64d7919ef38eb9ad0000000100000fa2
 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>=&gt;</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>=&gt;</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>=&gt;</prompt> <userinput>SELECT * FROM t1 INNER JOIN t2 USING (num);</userinput>
 num | name | value
-----+------+-------
   1 | a    | xxx
   3 | c    | yyy
(2 rows)

<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 NATURAL INNER JOIN t2;</userinput>
 num | name | value
-----+------+-------
   1 | a    | xxx
   3 | c    | yyy
(2 rows)

<prompt>=&gt;</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>=&gt;</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>=&gt;</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>=&gt;</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>=&gt;</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

Title: SQL Join Types and Examples
Summary
This section provides detailed explanations and examples of various SQL join types, including CROSS JOIN, INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL JOIN. It demonstrates how different join conditions (ON, USING, and NATURAL) affect the result set. The text includes sample tables and query results to illustrate the behavior of each join type. It also explains how the ON clause can include conditions not directly related to the join, which can be useful but requires careful consideration. The examples show how different joins handle matching and non-matching rows, as well as how they deal with NULL values in the output.