diff options
author | Noah Misch <noah@leadboat.com> | 2013-07-16 20:15:36 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2013-07-16 20:15:36 -0400 |
commit | b560ec1b0d7b910ce13edc51ffaafaca72136e3b (patch) | |
tree | ae5d80c94681788fd214efe6d61425089850781e /doc/src | |
parent | 7a8e9f298e7b8158296e1ea72ca8987323c10edf (diff) | |
download | postgresql-b560ec1b0d7b910ce13edc51ffaafaca72136e3b.tar.gz postgresql-b560ec1b0d7b910ce13edc51ffaafaca72136e3b.zip |
Implement the FILTER clause for aggregate function calls.
This is SQL-standard with a few extensions, namely support for
subqueries and outer references in clause expressions.
catversion bump due to change in Aggref and WindowFunc.
David Fetter, reviewed by Dean Rasheed.
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/keywords.sgml | 2 | ||||
-rw-r--r-- | doc/src/sgml/ref/select.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/syntax.sgml | 48 |
3 files changed, 41 insertions, 14 deletions
diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml index 059c8e468f4..ecfde993da3 100644 --- a/doc/src/sgml/keywords.sgml +++ b/doc/src/sgml/keywords.sgml @@ -1786,7 +1786,7 @@ </row> <row> <entry><token>FILTER</token></entry> - <entry></entry> + <entry>non-reserved</entry> <entry>reserved</entry> <entry>reserved</entry> <entry></entry> diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index 68309ba94da..b0cec1421ca 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -598,6 +598,11 @@ GROUP BY <replaceable class="parameter">expression</replaceable> [, ...] making up each group, producing a separate value for each group (whereas without <literal>GROUP BY</literal>, an aggregate produces a single value computed across all the selected rows). + The set of rows fed to the aggregate function can be further filtered by + attaching a <literal>FILTER</literal> clause to the aggregate function + call; see <xref linkend="syntax-aggregates"> for more information. When + a <literal>FILTER</literal> clause is present, only those rows matching it + are included. When <literal>GROUP BY</literal> is present, it is not valid for the <command>SELECT</command> list expressions to refer to ungrouped columns except within aggregate functions or if the diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index b1392124a9e..803ed855c82 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1554,6 +1554,10 @@ sqrt(2) <secondary>invocation</secondary> </indexterm> + <indexterm zone="syntax-aggregates"> + <primary>filter</primary> + </indexterm> + <para> An <firstterm>aggregate expression</firstterm> represents the application of an aggregate function across the rows selected by a @@ -1562,19 +1566,19 @@ sqrt(2) syntax of an aggregate expression is one of the following: <synopsis> -<replaceable>aggregate_name</replaceable> (<replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) -<replaceable>aggregate_name</replaceable> (ALL <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) -<replaceable>aggregate_name</replaceable> (DISTINCT <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) -<replaceable>aggregate_name</replaceable> ( * ) +<replaceable>aggregate_name</replaceable> (<replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] +<replaceable>aggregate_name</replaceable> (ALL <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] +<replaceable>aggregate_name</replaceable> (DISTINCT <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] +<replaceable>aggregate_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] </synopsis> where <replaceable>aggregate_name</replaceable> is a previously - defined aggregate (possibly qualified with a schema name), + defined aggregate (possibly qualified with a schema name) and <replaceable>expression</replaceable> is any value expression that does not itself contain an aggregate - expression or a window function call, and - <replaceable>order_by_clause</replaceable> is a optional - <literal>ORDER BY</> clause as described below. + expression or a window function call. The optional + <replaceable>order_by_clause</replaceable> and + <replaceable>filter_clause</replaceable> are described below. </para> <para> @@ -1607,6 +1611,23 @@ sqrt(2) </para> <para> + If <literal>FILTER</literal> is specified, then only the input + rows for which the <replaceable>filter_clause</replaceable> + evaluates to true are fed to the aggregate function; other rows + are discarded. For example: +<programlisting> +SELECT + count(*) AS unfiltered, + count(*) FILTER (WHERE i < 5) AS filtered +FROM generate_series(1,10) AS s(i); + unfiltered | filtered +------------+---------- + 10 | 4 +(1 row) +</programlisting> + </para> + + <para> Ordinarily, the input rows are fed to the aggregate function in an unspecified order. In many cases this does not matter; for example, <function>min</> produces the same result no matter what order it @@ -1709,10 +1730,10 @@ SELECT string_agg(a ORDER BY a, ',') FROM table; -- incorrect The syntax of a window function call is one of the following: <synopsis> -<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) OVER ( <replaceable class="parameter">window_definition</replaceable> ) -<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) OVER <replaceable>window_name</replaceable> -<replaceable>function_name</replaceable> ( * ) OVER ( <replaceable class="parameter">window_definition</replaceable> ) -<replaceable>function_name</replaceable> ( * ) OVER <replaceable>window_name</replaceable> +<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER ( <replaceable class="parameter">window_definition</replaceable> ) +<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER <replaceable>window_name</replaceable> +<replaceable>function_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER ( <replaceable class="parameter">window_definition</replaceable> ) +<replaceable>function_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER <replaceable>window_name</replaceable> </synopsis> where <replaceable class="parameter">window_definition</replaceable> has the syntax @@ -1836,7 +1857,8 @@ UNBOUNDED FOLLOWING The built-in window functions are described in <xref linkend="functions-window-table">. Other window functions can be added by the user. Also, any built-in or user-defined aggregate function can be - used as a window function. + used as a window function. Only aggregate window functions accept + a <literal>FILTER</literal> clause. </para> <para> |