head	1.5;
access;
symbols
	REL9_0_0:1.4.14.1
	REL9_1_ALPHA1:1.5
	REL9_0_RC1:1.4.14.1
	REL9_0_BETA4:1.4.14.1
	REL9_0_STABLE:1.4.0.14
	REL9_0_BETA3:1.4
	REL9_0_BETA2:1.4
	REL8_3_11:1.3
	REL8_4_4:1.4
	REL9_0_BETA1:1.4
	REL9_0_ALPHA5_BRANCH:1.4.0.12
	REL9_0_ALPHA5:1.4
	REL8_3_10:1.3
	REL8_4_3:1.4
	REL9_0_ALPHA4:1.4
	REL9_0_ALPHA4_BRANCH:1.4.0.10
	REL8_5_ALPHA3:1.4
	REL8_5_ALPHA3_BRANCH:1.4.0.8
	REL8_3_9:1.3
	REL8_4_2:1.4
	REL8_5_ALPHA2:1.4
	REL8_5_ALPHA2_BRANCH:1.4.0.6
	REL8_3_8:1.3
	REL8_4_1:1.4
	REL8_5_ALPHA1:1.4
	REL8_5_ALPHA1_BRANCH:1.4.0.4
	REL8_4_STABLE:1.4.0.2
	REL8_4_0:1.4
	REL8_4_RC2:1.4
	REL8_4_RC1:1.4
	REL8_4_BETA2:1.4
	REL8_4_BETA1:1.4
	REL8_3_7:1.3
	REL8_3_6:1.3
	REL8_3_5:1.3
	REL8_3_4:1.3
	REL8_3_3:1.3
	REL8_3_2:1.3
	REL8_3_1:1.3
	REL8_3_STABLE:1.3.0.2
	REL8_3_0:1.3
	REL8_3_RC2:1.3
	REL8_3_RC1:1.3
	REL8_3_BETA4:1.2
	REL8_3_BETA3:1.2;
locks; strict;
comment	@# @;


1.5
date	2010.07.29.19.34.40;	author petere;	state Exp;
branches;
next	1.4;

1.4
date	2008.11.14.19.58.45;	author tgl;	state Exp;
branches
	1.4.14.1;
next	1.3;

1.3
date	2007.12.10.05.32.51;	author tgl;	state Exp;
branches;
next	1.2;

1.2
date	2007.11.11.14.23.18;	author momjian;	state Exp;
branches;
next	1.1;

1.1
date	2007.11.10.23.30.46;	author momjian;	state Exp;
branches;
next	;

1.4.14.1
date	2010.07.29.19.34.36;	author petere;	state Exp;
branches;
next	;


desc
@@


1.5
log
@Fix indentation of verbatim block elements

Block elements with verbatim formatting (literallayout, programlisting,
screen, synopsis) should be aligned at column 0 independent of the surrounding
SGML, because whitespace is significant, and indenting them creates erratic
whitespace in the output.  The CSS stylesheets already take care of indenting
the output.

Assorted markup improvements to go along with it.
@
text
@<!-- $PostgreSQL: pgsql/doc/src/sgml/intagg.sgml,v 1.4 2008/11/14 19:58:45 tgl Exp $ -->

<sect1 id="intagg">
 <title>intagg</title>

 <indexterm zone="intagg">
  <primary>intagg</primary>
 </indexterm>

 <para>
  The <filename>intagg</filename> module provides an integer aggregator and an
  enumerator.  <filename>intagg</filename> is now obsolete, because there
  are built-in functions that provide a superset of its capabilities.
  However, the module is still provided as a compatibility wrapper around
  the built-in functions.
 </para>

 <sect2>
  <title>Functions</title>

 <para>
  The aggregator is an aggregate function
  <function>int_array_aggregate(integer)</>
  that produces an integer array
  containing exactly the integers it is fed.
  This is a wrapper around <function>array_agg</>,
  which does the same thing for any array type.
 </para>

 <para>
  The enumerator is a function
  <function>int_array_enum(integer[])</>
  that returns <type>setof integer</>.  It is essentially the reverse
  operation of the aggregator: given an array of integers, expand it
  into a set of rows.  This is a wrapper around <function>unnest</>,
  which does the same thing for any array type.
 </para>

 </sect2>

 <sect2>
  <title>Sample Uses</title>

  <para>
   Many database systems have the notion of a one to many table. Such a table
   usually sits between two indexed tables, for example:

<programlisting>
CREATE TABLE left (id INT PRIMARY KEY, ...);
CREATE TABLE right (id INT PRIMARY KEY, ...);
CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
</programlisting>

  It is typically used like this:

<programlisting>
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
  WHERE one_to_many.left = <replaceable>item</>;
</programlisting>

  This will return all the items in the right hand table for an entry
  in the left hand table. This is a very common construct in SQL.
 </para>

 <para>
  Now, this methodology can be cumbersome with a very large number of
  entries in the <structname>one_to_many</> table.  Often,
  a join like this would result in an index scan
  and a fetch for each right hand entry in the table for a particular
  left hand entry. If you have a very dynamic system, there is not much you
  can do. However, if you have some data which is fairly static, you can
  create a summary table with the aggregator.

<programlisting>
CREATE TABLE summary AS
  SELECT left, int_array_aggregate(right) AS right
  FROM one_to_many
  GROUP BY left;
</programlisting>

  This will create a table with one row per left item, and an array
  of right items. Now this is pretty useless without some way of using
  the array; that's why there is an array enumerator.  You can do

<programlisting>
SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</>;
</programlisting>

  The above query using <function>int_array_enum</> produces the same results
  as

<programlisting>
SELECT left, right FROM one_to_many WHERE left = <replaceable>item</>;
</programlisting>

  The difference is that the query against the summary table has to get
  only one row from the table, whereas the direct query against
  <structname>one_to_many</> must index scan and fetch a row for each entry.
 </para>

 <para>
  On one system, an <command>EXPLAIN</> showed a query with a cost of 8488 was
  reduced to a cost of 329.  The original query was a join involving the
  <structname>one_to_many</> table, which was replaced by:

<programlisting>
SELECT right, count(right) FROM
  ( SELECT left, int_array_enum(right) AS right
    FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</>) AS lefts
         ON (summary.left = lefts.left)
  ) AS list
  GROUP BY right
  ORDER BY count DESC;
</programlisting>
 </para>

 </sect2>

</sect1>
@


1.4
log
@Reduce contrib/intagg to a thin wrapper around the new core functions
array_agg() and unnest().  We could drop it entirely in the future,
but let's keep it for a release or two as a compatibility assist.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/intagg.sgml,v 1.3 2007/12/10 05:32:51 tgl Exp $ -->
a46 1
  </para>
d48 1
a48 1
 <programlisting>
d52 1
a52 1
 </programlisting>
a53 1
 <para>
a54 1
 </para>
d56 4
a59 4
 <programlisting>
  SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
    WHERE one_to_many.left = <replaceable>item</>;
 </programlisting>
a60 1
 <para>
a72 1
 </para>
d74 2
a75 2
 <programlisting>
CREATE TABLE summary as
d79 1
a79 1
 </programlisting>
a80 1
 <para>
a83 1
 </para>
d85 1
a85 1
 <programlisting>
d87 1
a87 1
 </programlisting>
a88 1
 <para>
a90 1
 </para>
d92 1
a92 1
 <programlisting>
d94 1
a94 1
 </programlisting>
a95 1
 <para>
a104 1
 </para>
d106 1
a106 1
 <programlisting>
d114 2
a115 1
 </programlisting>
@


1.4.14.1
log
@Fix indentation of verbatim block elements

Block elements with verbatim formatting (literallayout, programlisting,
screen, synopsis) should be aligned at column 0 independent of the surrounding
SGML, because whitespace is significant, and indenting them creates erratic
whitespace in the output.  The CSS stylesheets already take care of indenting
the output.

Assorted markup improvements to go along with it.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/intagg.sgml,v 1.4 2008/11/14 19:58:45 tgl Exp $ -->
d47 1
d49 1
a49 1
<programlisting>
d53 1
a53 1
</programlisting>
d55 1
d57 1
d59 4
a62 4
<programlisting>
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
  WHERE one_to_many.left = <replaceable>item</>;
</programlisting>
d64 1
d77 1
d79 2
a80 2
<programlisting>
CREATE TABLE summary AS
d84 1
a84 1
</programlisting>
d86 1
d90 1
d92 1
a92 1
<programlisting>
d94 1
a94 1
</programlisting>
d96 1
d99 1
d101 1
a101 1
<programlisting>
d103 1
a103 1
</programlisting>
d105 1
d115 1
d117 1
a117 1
<programlisting>
d125 1
a125 2
</programlisting>
 </para>
@


1.3
log
@Make an editorial pass over the newly SGML-ified contrib documentation.
Fix lots of bad markup, bad English, bad explanations.

Second round of commits.  pgcrypto and pgstandby still to go...
@
text
@d1 1
a1 1
<!-- $PostgreSQL$ -->
d12 4
a15 1
  enumerator.
d26 2
a27 1
  Here is a not-tremendously-useful example:
a29 9
 <programlisting>
test=# select int_array_aggregate(i) from
test-#   generate_series(1,10,2) i;
 int_array_aggregate
---------------------
 {1,3,5,7,9}
(1 row)
 </programlisting>

d35 2
a36 1
  into a set of rows.  For example,
a38 12
 <programlisting>
test=# select * from int_array_enum(array[1,3,5,7,9]);
 int_array_enum
----------------
              1
              3
              5
              7
              9
(5 rows)
 </programlisting>

@


1.2
log
@Remove tabs from SGML files.
@
text
@d1 1
d5 1
a5 1
 
d11 13
a23 1
  This section describes the <literal>intagg</literal> module which provides an integer aggregator and an enumerator.
d25 10
d36 5
a40 1
  Many database systems have the notion of a one to many table. Such a table usually sits between two indexed tables, as: 
d42 23
d66 3
a68 1
CREATE TABLE one_to_many(left INT, right INT) ;
d72 1
a72 1
  And it is used like this:
d76 2
a77 2
  SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right) 
        WHERE  one_to_many.left = item;
d81 1
a81 1
  This will return all the items in the right hand table for an entry 
d87 2
a88 2
  entries in the one_to_many table. Depending on the order in which
  data was entered, a join like this could result in an index scan
d90 1
a90 1
  left hand entry. If you have a very dynamic system, there is not much you 
d96 4
a99 2
CREATE TABLE summary as SELECT left, int_array_aggregate(right) 
        AS right FROM one_to_many GROUP BY left;
d105 1
a105 1
  the array, thats why there is an array enumerator.
d107 1
d109 1
a109 1
SELECT left, int_array_enum(right) FROM summary WHERE left = item;
d113 2
a114 1
  The above query using int_array_enum, produces the same results as:
d116 1
d118 1
a118 1
SELECT left, right FROM one_to_many WHERE left = item;
d120 1
a120 1
 
d123 2
a124 2
  only one row from the table, where as the query against "one_to_many"
  must index scan and fetch a row for each entry.
d126 1
d128 3
a130 2
  On our system, an EXPLAIN shows a query with a cost of 8488 gets reduced
  to a cost of 329. The query is a join between the one_to_many table,
d132 1
d134 7
a140 6
SELECT right, count(right) FROM 
(
        SELECT left, int_array_enum(right) AS right FROM summary JOIN
                (SELECT left FROM left_table WHERE left = item) AS lefts
                 ON (summary.left = lefts.left ) 
) AS list GROUP BY right ORDER BY count DESC ;
d142 3
a145 1

@


1.1
log
@Move most /contrib README files into SGML.  Some still need conversion
or will never be converted.
@
text
@d25 1
a25 1
	WHERE  one_to_many.left = item;
d45 1
a45 1
	AS right FROM one_to_many GROUP BY left;
d76 1
a76 1
	SELECT left, int_array_enum(right) AS right FROM summary JOIN
@

