Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > c87b2b497674629a1400410f06a9ef63 > files > 577

postgresql-docs-7.3.2-5mdk.ppc.rpm

<HTML
><HEAD
><TITLE
>Extending SQL: Aggregates</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.73
"><LINK
REV="MADE"
HREF="mailto:pgsql-docs@postgresql.org"><LINK
REL="HOME"
TITLE="PostgreSQL 7.3.2 Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="Server Programming"
HREF="programmer-server.html"><LINK
REL="PREVIOUS"
TITLE="Operator Optimization Information"
HREF="xoper-optimization.html"><LINK
REL="NEXT"
TITLE="The Rule System"
HREF="rules.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
NAME="creation"
CONTENT="2003-02-03T20:17:34"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>PostgreSQL 7.3.2 Documentation</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="xoper-optimization.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="rules.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="XAGGR"
>Chapter 12. Extending <SPAN
CLASS="ACRONYM"
>SQL</SPAN
>: Aggregates</A
></H1
><A
NAME="AEN32614"
></A
><P
>   Aggregate functions  in <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> 
   are expressed as <I
CLASS="FIRSTTERM"
>state values</I
>
   and <I
CLASS="FIRSTTERM"
>state transition functions</I
>.
   That is,  an  aggregate  can  be
   defined  in terms of state that is modified whenever an
   input item is processed.  To define a new aggregate
   function, one selects a data type for the state value,
   an initial value for the state, and a state transition
   function.  The state transition function is just an
   ordinary function that could also be used outside the
   context of the aggregate.  A <I
CLASS="FIRSTTERM"
>final function</I
>
   can also be specified, in case the desired output of the aggregate
   is different from the data that needs to be kept in the running
   state value.
  </P
><P
>   Thus, in addition to the input and result data types seen by a user
   of the aggregate, there is an internal state-value data type that
   may be different from both the input and result types.
  </P
><P
>   If we define an aggregate that does not use a final function,
   we have an aggregate that computes a running function of
   the column values from each row.  <TT
CLASS="FUNCTION"
>Sum</TT
>  is  an
   example  of  this  kind  of aggregate.  <TT
CLASS="FUNCTION"
>Sum</TT
> starts at
   zero and always adds the current  row's  value  to
   its  running  total.  For example, if we want to make a <TT
CLASS="FUNCTION"
>sum</TT
>
   aggregate to work on a data type for complex numbers,
   we only need the addition function for that data type.
   The aggregate definition is:
   
</P><PRE
CLASS="PROGRAMLISTING"
>CREATE AGGREGATE complex_sum (
    sfunc = complex_add,
    basetype = complex,
    stype = complex,
    initcond = '(0,0)'
);</PRE
><P>

</P><PRE
CLASS="SCREEN"
>SELECT complex_sum(a) FROM test_complex;

 complex_sum
-------------
 (34,53.9)</PRE
><P>

   (In practice, we'd just name the aggregate <TT
CLASS="FUNCTION"
>sum</TT
>, and rely on
   <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> to figure out which kind
   of sum to apply to a column of type <TT
CLASS="TYPE"
>complex</TT
>.)
  </P
><P
>   The above definition of <TT
CLASS="FUNCTION"
>sum</TT
> will return zero (the initial
   state condition) if there are no non-null input values.
   Perhaps we want to return NULL in that case instead --- the SQL standard
   expects <TT
CLASS="FUNCTION"
>sum</TT
> to behave that way.  We can do this simply by
   omitting the <TT
CLASS="LITERAL"
>initcond</TT
> phrase, so that the initial state
   condition is NULL.  Ordinarily this would mean that the <TT
CLASS="LITERAL"
>sfunc</TT
>
   would need to check for a NULL state-condition input, but for
   <TT
CLASS="FUNCTION"
>sum</TT
> and some other simple aggregates like <TT
CLASS="FUNCTION"
>max</TT
> and <TT
CLASS="FUNCTION"
>min</TT
>,
   it's sufficient to insert the first non-null input value into
   the state variable and then start applying the transition function
   at the second non-null input value.  <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
>
   will do that automatically if the initial condition is NULL and
   the transition function is marked <SPAN
CLASS="QUOTE"
>"strict"</SPAN
> (i.e., not to be called
   for NULL inputs).
  </P
><P
>   Another bit of default behavior for a <SPAN
CLASS="QUOTE"
>"strict"</SPAN
> transition function
   is that the previous state value is retained unchanged whenever a
   NULL input value is encountered.  Thus, null values are ignored.  If you
   need some other behavior for NULL inputs, just define your transition
   function as non-strict, and code it to test for NULL inputs and do
   whatever is needed.
  </P
><P
>   <TT
CLASS="FUNCTION"
>Avg</TT
> (average) is a more complex example of an aggregate.  It requires
   two pieces of running state: the sum of the inputs and the count
   of the number of inputs.  The final result is obtained by dividing
   these quantities.  Average is typically implemented by using a
   two-element array as the transition state value.  For example,
   the built-in implementation of <TT
CLASS="FUNCTION"
>avg(float8)</TT
>
   looks like:

</P><PRE
CLASS="PROGRAMLISTING"
>CREATE AGGREGATE avg (
    sfunc = float8_accum,
    basetype = float8,
    stype = float8[],
    finalfunc = float8_avg,
    initcond = '{0,0}'
);</PRE
><P>
  </P
><P
>   For further details see the description of the <TT
CLASS="COMMAND"
>CREATE
   AGGREGATE</TT
> command in the <I
CLASS="CITETITLE"
>Reference
   Manual</I
>.
  </P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="xoper-optimization.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="rules.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Operator Optimization Information</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="programmer-server.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The Rule System</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>