aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/func/func-subquery.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/func/func-subquery.sgml')
-rw-r--r--doc/src/sgml/func/func-subquery.sgml349
1 files changed, 349 insertions, 0 deletions
diff --git a/doc/src/sgml/func/func-subquery.sgml b/doc/src/sgml/func/func-subquery.sgml
new file mode 100644
index 00000000000..a9f2b12e48c
--- /dev/null
+++ b/doc/src/sgml/func/func-subquery.sgml
@@ -0,0 +1,349 @@
+ <sect1 id="functions-subquery">
+ <title>Subquery Expressions</title>
+
+ <indexterm>
+ <primary>EXISTS</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ALL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>subquery</primary>
+ </indexterm>
+
+ <para>
+ This section describes the <acronym>SQL</acronym>-compliant subquery
+ expressions available in <productname>PostgreSQL</productname>.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </para>
+
+ <sect2 id="functions-subquery-exists">
+ <title><literal>EXISTS</literal></title>
+
+<synopsis>
+EXISTS (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The argument of <token>EXISTS</token> is an arbitrary <command>SELECT</command> statement,
+ or <firstterm>subquery</firstterm>. The
+ subquery is evaluated to determine whether it returns any rows.
+ If it returns at least one row, the result of <token>EXISTS</token> is
+ <quote>true</quote>; if the subquery returns no rows, the result of <token>EXISTS</token>
+ is <quote>false</quote>.
+ </para>
+
+ <para>
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ </para>
+
+ <para>
+ The subquery will generally only be executed long enough to determine
+ whether at least one row is returned, not all the way to completion.
+ It is unwise to write a subquery that has side effects (such as
+ calling sequence functions); whether the side effects occur
+ might be unpredictable.
+ </para>
+
+ <para>
+ Since the result depends only on whether any rows are returned,
+ and not on the contents of those rows, the output list of the
+ subquery is normally unimportant. A common coding convention is
+ to write all <literal>EXISTS</literal> tests in the form
+ <literal>EXISTS(SELECT 1 WHERE ...)</literal>. There are exceptions to
+ this rule however, such as subqueries that use <token>INTERSECT</token>.
+ </para>
+
+ <para>
+ This simple example is like an inner join on <literal>col2</literal>, but
+ it produces at most one output row for each <literal>tab1</literal> row,
+ even if there are several matching <literal>tab2</literal> rows:
+<screen>
+SELECT col1
+FROM tab1
+WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-in">
+ <title><literal>IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</quote> if any equal subquery row is found.
+ The result is <quote>false</quote> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>IN</token> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</quote> if any equal subquery row is found.
+ The result is <quote>false</quote> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>IN</token> is null.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-notin">
+ <title><literal>NOT IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</quote> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any equal row is found.
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>NOT IN</token> construct will be null, not true.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>NOT IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</quote> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any equal row is found.
+ </para>
+
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>NOT IN</token> is null.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-any-some">
+ <title><literal>ANY</literal>/<literal>SOME</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ANY</token> is <quote>true</quote> if any true result is obtained.
+ The result is <quote>false</quote> if no true result is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ <token>IN</token> is equivalent to <literal>= ANY</literal>.
+ </para>
+
+ <para>
+ Note that if there are no successes and at least one right-hand row yields
+ null for the operator's result, the result of the <token>ANY</token> construct
+ will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>ANY</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ANY</token> is <quote>true</quote> if the comparison
+ returns true for any subquery row.
+ The result is <quote>false</quote> if the comparison returns false for every
+ subquery row (including the case where the subquery returns no
+ rows).
+ The result is NULL if no comparison with a subquery row returns true,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-all">
+ <title><literal>ALL</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ALL</token> is <quote>true</quote> if all rows yield true
+ (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any false result is found.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ <token>NOT IN</token> is equivalent to <literal>&lt;&gt; ALL</literal>.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>ALL</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ALL</token> is <quote>true</quote> if the comparison
+ returns true for all subquery rows (including the
+ case where the subquery returns no rows).
+ The result is <quote>false</quote> if the comparison returns false for any
+ subquery row.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-single-row-comp">
+ <title>Single-Row Comparison</title>
+
+ <indexterm zone="functions-subquery">
+ <primary>comparison</primary>
+ <secondary>subquery result row</secondary>
+ </indexterm>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized subquery, which must return exactly
+ as many columns as there are expressions in the left-hand row. Furthermore,
+ the subquery cannot return more than one row. (If it returns zero rows,
+ the result is taken to be null.) The left-hand side is evaluated and
+ compared row-wise to the single subquery result row.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+ </sect1>