summaryrefslogtreecommitdiff
path: root/doc/src/sgml/tablefunc.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/tablefunc.sgml')
-rw-r--r--doc/src/sgml/tablefunc.sgml198
1 files changed, 93 insertions, 105 deletions
diff --git a/doc/src/sgml/tablefunc.sgml b/doc/src/sgml/tablefunc.sgml
index d71890fcaa8..be41e838405 100644
--- a/doc/src/sgml/tablefunc.sgml
+++ b/doc/src/sgml/tablefunc.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/tablefunc.sgml,v 1.4 2007/12/06 04:12:10 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/tablefunc.sgml,v 1.5 2010/07/29 19:34:40 petere Exp $ -->
<sect1 id="tablefunc">
<title>tablefunc</title>
@@ -94,9 +94,9 @@
<sect3>
<title><function>normal_rand</function></title>
- <programlisting>
+<synopsis>
normal_rand(int numvals, float8 mean, float8 stddev) returns setof float8
- </programlisting>
+</synopsis>
<para>
<function>normal_rand</> produces a set of normally distributed random
@@ -115,7 +115,7 @@ normal_rand(int numvals, float8 mean, float8 stddev) returns setof float8
standard deviation of 3:
</para>
- <programlisting>
+<screen>
test=# SELECT * FROM normal_rand(1000, 5, 3);
normal_rand
----------------------
@@ -131,22 +131,22 @@ test=# SELECT * FROM normal_rand(1000, 5, 3);
9.71308014517282
2.49639286969028
(1000 rows)
- </programlisting>
+</screen>
</sect3>
<sect3>
<title><function>crosstab(text)</function></title>
- <programlisting>
+<synopsis>
crosstab(text sql)
crosstab(text sql, int N)
- </programlisting>
+</synopsis>
<para>
The <function>crosstab</> function is used to produce <quote>pivot</>
displays, wherein data is listed across the page rather than down.
For example, we might have data like
- <programlisting>
+<programlisting>
row1 val11
row1 val12
row1 val13
@@ -155,13 +155,13 @@ row2 val21
row2 val22
row2 val23
...
- </programlisting>
+</programlisting>
which we wish to display like
- <programlisting>
+<programlisting>
row1 val11 val12 val13 ...
row2 val21 val22 val23 ...
...
- </programlisting>
+</programlisting>
The <function>crosstab</> function takes a text parameter that is a SQL
query producing raw data formatted in the first way, and produces a table
formatted in the second way.
@@ -180,8 +180,6 @@ row2 val21 val22 val23 ...
<para>
For example, the provided query might produce a set something like:
- </para>
-
<programlisting>
row_name cat value
----------+-------+-------
@@ -194,29 +192,25 @@ row2 val21 val22 val23 ...
row2 cat3 val7
row2 cat4 val8
</programlisting>
+ </para>
<para>
The <function>crosstab</> function is declared to return <type>setof
record</type>, so the actual names and types of the output columns must be
defined in the <literal>FROM</> clause of the calling <command>SELECT</>
statement, for example:
- </para>
-
- <programlisting>
- SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);
- </programlisting>
-
- <para>
+<programlisting>
+SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);
+</programlisting>
This example produces a set something like:
- </para>
-
- <programlisting>
+<programlisting>
&lt;== value columns ==&gt;
-row_name category_1 category_2
- ---------+------------+------------
- row1 val1 val2
- row2 val5 val6
- </programlisting>
+ row_name category_1 category_2
+----------+------------+------------
+ row1 val1 val2
+ row2 val5 val6
+</programlisting>
+ </para>
<para>
The <literal>FROM</> clause must define the output as one
@@ -250,9 +244,7 @@ row_name category_1 category_2
<para>
Here is a complete example:
- </para>
-
- <programlisting>
+<programlisting>
CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
@@ -276,7 +268,8 @@ AS ct(row_name text, category_1 text, category_2 text, category_3 text);
test1 | val2 | val3 |
test2 | val6 | val7 |
(2 rows)
- </programlisting>
+</programlisting>
+ </para>
<para>
You can avoid always having to write out a <literal>FROM</> clause to
@@ -291,9 +284,9 @@ AS ct(row_name text, category_1 text, category_2 text, category_3 text);
<sect3>
<title><function>crosstab<replaceable>N</>(text)</function></title>
- <programlisting>
+<synopsis>
crosstab<replaceable>N</>(text sql)
- </programlisting>
+</synopsis>
<para>
The <function>crosstab<replaceable>N</></> functions are examples of how
@@ -304,7 +297,7 @@ crosstab<replaceable>N</>(text sql)
<function>crosstab4</>, whose output rowtypes are defined as
</para>
- <programlisting>
+<programlisting>
CREATE TYPE tablefunc_crosstab_N AS (
row_name TEXT,
category_1 TEXT,
@@ -314,7 +307,7 @@ CREATE TYPE tablefunc_crosstab_N AS (
.
category_N TEXT
);
- </programlisting>
+</programlisting>
<para>
Thus, these functions can be used directly when the input query produces
@@ -327,23 +320,21 @@ CREATE TYPE tablefunc_crosstab_N AS (
<para>
For instance, the example given in the previous section would also
work as
- </para>
-
- <programlisting>
+<programlisting>
SELECT *
FROM crosstab3(
'select rowid, attribute, value
from ct
where attribute = ''att2'' or attribute = ''att3''
order by 1,2');
- </programlisting>
+</programlisting>
+ </para>
<para>
These functions are provided mostly for illustration purposes. You
can create your own return types and functions based on the
underlying <function>crosstab()</> function. There are two ways
to do it:
- </para>
<itemizedlist>
<listitem>
@@ -355,52 +346,52 @@ FROM crosstab3(
<function>crosstab</> C function. For example, if your source data
produces row names that are <type>text</>, and values that are
<type>float8</>, and you want 5 value columns:
- </para>
+<programlisting>
+CREATE TYPE my_crosstab_float8_5_cols AS (
+ my_row_name text,
+ my_category_1 float8,
+ my_category_2 float8,
+ my_category_3 float8,
+ my_category_4 float8,
+ my_category_5 float8
+);
- <programlisting>
- CREATE TYPE my_crosstab_float8_5_cols AS (
- my_row_name text,
- my_category_1 float8,
- my_category_2 float8,
- my_category_3 float8,
- my_category_4 float8,
- my_category_5 float8
- );
-
- CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text)
- RETURNS setof my_crosstab_float8_5_cols
- AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
- </programlisting>
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text)
+ RETURNS setof my_crosstab_float8_5_cols
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</programlisting>
+ </para>
</listitem>
<listitem>
<para>
Use <literal>OUT</> parameters to define the return type implicitly.
The same example could also be done this way:
+<programlisting>
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(
+ IN text,
+ OUT my_row_name text,
+ OUT my_category_1 float8,
+ OUT my_category_2 float8,
+ OUT my_category_3 float8,
+ OUT my_category_4 float8,
+ OUT my_category_5 float8)
+ RETURNS setof record
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</programlisting>
</para>
-
- <programlisting>
- CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(IN text,
- OUT my_row_name text,
- OUT my_category_1 float8,
- OUT my_category_2 float8,
- OUT my_category_3 float8,
- OUT my_category_4 float8,
- OUT my_category_5 float8)
- RETURNS setof record
- AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
- </programlisting>
</listitem>
</itemizedlist>
+ </para>
</sect3>
<sect3>
<title><function>crosstab(text, text)</function></title>
- <programlisting>
+<synopsis>
crosstab(text source_sql, text category_sql)
- </programlisting>
+</synopsis>
<para>
The main limitation of the single-parameter form of <function>crosstab</>
@@ -432,8 +423,7 @@ crosstab(text source_sql, text category_sql)
<para>
For example, <parameter>source_sql</parameter> might produce a set
something like:
- </para>
- <programlisting>
+<programlisting>
SELECT row_name, extra_col, cat, value FROM foo ORDER BY 1;
row_name extra_col cat value
@@ -445,7 +435,8 @@ crosstab(text source_sql, text category_sql)
row2 extra2 cat2 val6
row2 extra2 cat3 val7
row2 extra2 cat4 val8
- </programlisting>
+</programlisting>
+ </para>
<para>
<parameter>category_sql</parameter> is a SQL statement that produces
@@ -453,9 +444,8 @@ crosstab(text source_sql, text category_sql)
It must produce at least one row, or an error will be generated.
Also, it must not produce duplicate values, or an error will be
generated. <parameter>category_sql</parameter> might be something like:
- </para>
- <programlisting>
+<programlisting>
SELECT DISTINCT cat FROM foo ORDER BY 1;
cat
-------
@@ -463,32 +453,32 @@ SELECT DISTINCT cat FROM foo ORDER BY 1;
cat2
cat3
cat4
- </programlisting>
+</programlisting>
+ </para>
<para>
The <function>crosstab</> function is declared to return <type>setof
record</type>, so the actual names and types of the output columns must be
defined in the <literal>FROM</> clause of the calling <command>SELECT</>
statement, for example:
- </para>
- <programlisting>
- SELECT * FROM crosstab('...', '...')
- AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text);
- </programlisting>
+<programlisting>
+SELECT * FROM crosstab('...', '...')
+ AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text);
+</programlisting>
+ </para>
<para>
This will produce a result something like:
+<programlisting>
+ &lt;== value columns ==&gt;
+row_name extra cat1 cat2 cat3 cat4
+---------+-------+------+------+------+------
+ row1 extra1 val1 val2 val4
+ row2 extra2 val5 val6 val7 val8
+</programlisting>
</para>
- <programlisting>
- &lt;== value columns ==&gt;
- row_name extra cat1 cat2 cat3 cat4
- ---------+-------+------+------+------+------
- row1 extra1 val1 val2 val4
- row2 extra2 val5 val6 val7 val8
- </programlisting>
-
<para>
The <literal>FROM</> clause must define the proper number of output
columns of the proper data types. If there are <replaceable>N</>
@@ -527,9 +517,7 @@ SELECT DISTINCT cat FROM foo ORDER BY 1;
<para>
Here are two complete examples:
- </para>
-
- <programlisting>
+<programlisting>
create table sales(year int, month int, qty int);
insert into sales values(2007, 1, 1000);
insert into sales values(2007, 2, 1500);
@@ -561,9 +549,9 @@ select * from crosstab(
2007 | 1000 | 1500 | | | | | 500 | | | | 1500 | 2000
2008 | 1000 | | | | | | | | | | |
(2 rows)
- </programlisting>
+</programlisting>
- <programlisting>
+<programlisting>
CREATE TABLE cth(rowid text, rowdt timestamp, attribute text, val text);
INSERT INTO cth VALUES('test1','01 March 2003','temperature','42');
INSERT INTO cth VALUES('test1','01 March 2003','test_result','PASS');
@@ -592,7 +580,8 @@ AS
test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
(2 rows)
- </programlisting>
+</programlisting>
+ </para>
<para>
You can create predefined functions to avoid having to write out
@@ -606,11 +595,11 @@ AS
<sect3>
<title><function>connectby</function></title>
- <programlisting>
+<synopsis>
connectby(text relname, text keyid_fld, text parent_keyid_fld
[, text orderby_fld ], text start_with, int max_depth
[, text branch_delim ])
- </programlisting>
+</synopsis>
<para>
The <function>connectby</> function produces a display of hierarchical
@@ -675,10 +664,10 @@ connectby(text relname, text keyid_fld, text parent_keyid_fld
statement, for example:
</para>
- <programlisting>
- SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
- AS t(keyid text, parent_keyid text, level int, branch text, pos int);
- </programlisting>
+<programlisting>
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text, pos int);
+</programlisting>
<para>
The first two output columns are used for the current row's key and
@@ -731,9 +720,7 @@ connectby(text relname, text keyid_fld, text parent_keyid_fld
<para>
Here is an example:
- </para>
-
- <programlisting>
+<programlisting>
CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);
INSERT INTO connectby_tree VALUES('row1',NULL, 0);
@@ -797,7 +784,8 @@ SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2'
row6 | row4 | 2 | 5
row8 | row6 | 3 | 6
(6 rows)
- </programlisting>
+</programlisting>
+ </para>
</sect3>
</sect2>