First attempt at a docs patch for aggregate order by.

-- 
Andrew.

Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.491
diff -c -r1.491 func.sgml
*** doc/src/sgml/func.sgml	21 Oct 2009 20:38:58 -0000	1.491
--- doc/src/sgml/func.sgml	13 Nov 2009 23:37:45 -0000
***************
*** 8459,8476 ****
      </para>
  
      <para>
!      To determine the order of the concatenation, something like the
!      following approach can be used:
  
  <screen><![CDATA[
! SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
          xmlagg
  ----------------------
   <bar/><foo>abc</foo>
  ]]></screen>
  
!      Again, see <xref linkend="functions-aggregate"> for additional
!      information.
      </para>
     </sect3>
  
--- 8459,8487 ----
      </para>
  
      <para>
!      To determine the order of the concatenation, an <literal>ORDER BY</>
!      clause may be added to the aggregate call as described in
!      <xref linkend="syntax-aggregates">. For example:
  
  <screen><![CDATA[
! SELECT xmlagg(x ORDER BY y DESC) FROM test;
          xmlagg
  ----------------------
   <bar/><foo>abc</foo>
  ]]></screen>
+     </para>
+ 
+     <para>
+      The following non-standard approach used to be recommended
+      in previous versions, and may still be useful in specific
+      cases:
  
! <screen><![CDATA[
! SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
!         xmlagg
! ----------------------
!  <bar/><foo>abc</foo>
! ]]></screen>
      </para>
     </sect3>
  
***************
*** 9887,9906 ****
     The aggregate functions <function>array_agg</function>
     and <function>xmlagg</function>, as well as similar user-defined
     aggregate functions, produce meaningfully different result values
!    depending on the order of the input values.  In the current
!    implementation, the order of the input is in principle unspecified.
!    Supplying the input values from a sorted subquery
!    will usually work, however.  For example:
  
  <screen><![CDATA[
  SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
  ]]></screen>
  
     But this syntax is not allowed in the SQL standard, and is
!    not portable to other database systems.  A future version of
!    <productname>PostgreSQL</> might provide an additional feature to control
!    the order in a better-defined way (<literal>xmlagg(expr ORDER BY expr, expr,
!    ...)</literal>).
    </para>
  
    <para>
--- 9898,9919 ----
     The aggregate functions <function>array_agg</function>
     and <function>xmlagg</function>, as well as similar user-defined
     aggregate functions, produce meaningfully different result values
!    depending on the order of the input values.  This ordering is
!    unspecified by default, but may be controlled by an
!    <literal>ORDER BY</> clause within the aggregate call as shown in
!    <xref linkend="syntax-aggregates">.
!   </para>
!    
!   <para>
!    Alternatively, supplying the input values from a sorted subquery
!    will usually work.  For example:
  
  <screen><![CDATA[
  SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
  ]]></screen>
  
     But this syntax is not allowed in the SQL standard, and is
!    not portable to other database systems.
    </para>
  
    <para>
Index: doc/src/sgml/syntax.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/syntax.sgml,v
retrieving revision 1.138
diff -c -r1.138 syntax.sgml
*** doc/src/sgml/syntax.sgml	5 Nov 2009 23:24:22 -0000	1.138
--- doc/src/sgml/syntax.sgml	13 Nov 2009 23:37:48 -0000
***************
*** 1525,1541 ****
      syntax of an aggregate expression is one of the following:
  
  <synopsis>
! <replaceable>aggregate_name</replaceable> (<replaceable>expression</replaceable> [ , ... ] )
! <replaceable>aggregate_name</replaceable> (ALL <replaceable>expression</replaceable> [ , ... ] )
! <replaceable>aggregate_name</replaceable> (DISTINCT <replaceable>expression</replaceable>)
  <replaceable>aggregate_name</replaceable> ( * )
  </synopsis>
  
      where <replaceable>aggregate_name</replaceable> is a previously
!     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.
     </para>
  
     <para>
--- 1525,1544 ----
      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> ( * )
  </synopsis>
  
      where <replaceable>aggregate_name</replaceable> is a previously
!     defined aggregate (possibly qualified with a schema name),
      <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 specified in <xref linkend="queries-order">
!     (though output column labels and ordinal column positions are excluded).
     </para>
  
     <para>
***************
*** 1561,1566 ****
--- 1564,1600 ----
     </para>
  
     <para>
+     Where the result of an aggregate function (such as <function>array_agg</>
+     or <function>xmlagg</>) depends on the ordering of its input, the optional
+     <replaceable>order_by_clause</> may be used to specify the desired ordering.
+     (If the clause is omitted, the ordering is unspecified.)  All features
+     normally available in an <literal>ORDER BY</> clause may be used, with the
+     exception of column name aliases or ordinal positions as sort expressions.
+    </para>
+ 
+    <para>
+     For example:
+ 
+ <programlisting>
+ SELECT array_agg(a ORDER BY b DESC NULLS LAST) FROM table;
+ </programlisting>
+    </para>
+ 
+    <para>
+     If <literal>DISTINCT</> is specified in addition to an <replaceable>order_by_clause</>,
+     then all the aggregate parameters must appear in the <replaceable>order_by_clause</>
+     prior to any other ordering expressions. (It is not necessary to include all the
+     aggregate parameters if no other expressions are present.)
+    </para>
+ 
+    <note>
+     <para>
+      The ability to specify both <literal>DISTINCT</> and <literal>ORDER BY</> in
+      an aggregate function is a <productname>PostgreSQL</> extension.
+     </para>
+    </note>
+ 
+    <para>
      The predefined aggregate functions are described in <xref
      linkend="functions-aggregate">.  Other aggregate functions can be added
      by the user.
***************
*** 1588,1600 ****
      appearing only in the result list or <literal>HAVING</> clause
      applies with respect to the query level that the aggregate belongs to.
     </para>
- 
-    <note>
-     <para>
-      <productname>PostgreSQL</productname> currently does not support
-      <literal>DISTINCT</> with more than one input expression.
-     </para>
-    </note>
    </sect2>
  
    <sect2 id="syntax-window-functions">
--- 1622,1627 ----
***************
*** 1697,1703 ****
      <literal>count(*) OVER (PARTITION BY x ORDER BY y)</>.
      <literal>*</> is customarily not used for non-aggregate window functions.
      Aggregate window functions, unlike normal aggregate functions, do not
!     allow <literal>DISTINCT</> to be used within the function argument list.
     </para>
  
     <para>
--- 1724,1731 ----
      <literal>count(*) OVER (PARTITION BY x ORDER BY y)</>.
      <literal>*</> is customarily not used for non-aggregate window functions.
      Aggregate window functions, unlike normal aggregate functions, do not
!     allow <literal>DISTINCT</> or <literal>ORDER BY</> to be used within the
!     function argument list.
     </para>
  
     <para>
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to