1
- <Chapter Id ="xaggr">
2
- <Title >Extending <Acronym >SQL</Acronym >: Aggregates</Title >
1
+ <chapter id ="xaggr">
2
+ <title >Extending <acronym >SQL</acronym >: Aggregates</title >
3
3
4
- <Para >
5
- Aggregate functions in <ProductName >Postgres</ProductName >
6
- are expressed as <firstterm>state values</firstterm>
7
- and <firstterm>state transition functions</firstterm>.
8
- That is, an aggregate can be
9
- defined in terms of state that is modified whenever an
10
- input item is processed. To define a new aggregate
11
- function, one selects a datatype for the state value,
12
- an initial value for the state, and a state transition
13
- function. The state transition function is just an
14
- ordinary function that could also be used outside the
15
- context of the aggregate.
16
- </Para >
4
+ <para >
5
+ Aggregate functions in <productname >Postgres</productname >
6
+ are expressed as <firstterm>state values</firstterm>
7
+ and <firstterm>state transition functions</firstterm>.
8
+ That is, an aggregate can be
9
+ defined in terms of state that is modified whenever an
10
+ input item is processed. To define a new aggregate
11
+ function, one selects a datatype for the state value,
12
+ an initial value for the state, and a state transition
13
+ function. The state transition function is just an
14
+ ordinary function that could also be used outside the
15
+ context of the aggregate.
16
+ </para >
17
17
18
- <Para >
19
- Actually, in order to make it easier to construct useful
20
- aggregates from existing functions, an aggregate can have
21
- one or two separate state values, one or two transition
22
- functions to update those state values, and a
23
- <firstterm>final function</firstterm> that computes the
24
- actual aggregate result from the ending state values.
25
- </Para >
18
+ <para >
19
+ Actually, in order to make it easier to construct useful
20
+ aggregates from existing functions, an aggregate can have
21
+ one or two separate state values, one or two transition
22
+ functions to update those state values, and a
23
+ <firstterm>final function</firstterm> that computes the
24
+ actual aggregate result from the ending state values.
25
+ </para >
26
26
27
- <Para >
28
- Thus there can be as many as four datatypes involved:
29
- the type of the input data items, the type of the aggregate's
30
- result, and the types of the two state values. Only the
31
- input and result datatypes are seen by a user of the aggregate.
32
- </Para >
27
+ <para >
28
+ Thus there can be as many as four datatypes involved:
29
+ the type of the input data items, the type of the aggregate's
30
+ result, and the types of the two state values. Only the
31
+ input and result datatypes are seen by a user of the aggregate.
32
+ </para >
33
33
34
- <Para >
35
- Some state transition functions need to look at each successive
36
- input to compute the next state value, while others ignore the
37
- specific input value and simply update their internal state.
38
- (The most useful example of the second kind is a running count
39
- of the number of input items.) The <ProductName >Postgres</ProductName >
40
- aggregate machinery defines <Acronym >sfunc1</Acronym > for
41
- an aggregate as a function that is passed both the old state
42
- value and the current input value, while <Acronym >sfunc2</Acronym >
43
- is a function that is passed only the old state value.
44
- </Para >
34
+ <para >
35
+ Some state transition functions need to look at each successive
36
+ input to compute the next state value, while others ignore the
37
+ specific input value and simply update their internal state.
38
+ (The most useful example of the second kind is a running count
39
+ of the number of input items.) The <productname >Postgres</productname >
40
+ aggregate machinery defines <acronym >sfunc1</acronym > for
41
+ an aggregate as a function that is passed both the old state
42
+ value and the current input value, while <acronym >sfunc2</acronym >
43
+ is a function that is passed only the old state value.
44
+ </para >
45
45
46
- <Para >
47
- If we define an aggregate that uses only <Acronym >sfunc1</Acronym >,
48
- we have an aggregate that computes a running function of
49
- the attribute values from each instance. "Sum" is an
50
- example of this kind of aggregate. "Sum" starts at
51
- zero and always adds the current instance's value to
52
- its running total. For example, if we want to make a Sum
53
- aggregate to work on a datatype for complex numbers,
54
- we only need the addition function for that datatype.
55
- The aggregate definition is:
56
-
57
- <ProgramListing >
46
+ <para >
47
+ If we define an aggregate that uses only <acronym >sfunc1</acronym >,
48
+ we have an aggregate that computes a running function of
49
+ the attribute values from each instance. "Sum" is an
50
+ example of this kind of aggregate. "Sum" starts at
51
+ zero and always adds the current instance's value to
52
+ its running total. For example, if we want to make a Sum
53
+ aggregate to work on a datatype for complex numbers,
54
+ we only need the addition function for that datatype.
55
+ The aggregate definition is:
56
+
57
+ <programlisting >
58
58
CREATE AGGREGATE complex_sum (
59
59
sfunc1 = complex_add,
60
60
basetype = complex,
@@ -69,27 +69,27 @@ SELECT complex_sum(a) FROM test_complex;
69
69
+------------+
70
70
|(34,53.9) |
71
71
+------------+
72
- </ProgramListing >
72
+ </programlisting >
73
73
74
- (In practice, we'd just name the aggregate "sum", and rely on
75
- <ProductName >Postgres</ProductName > to figure out which kind
76
- of sum to apply to a complex column.)
77
- </Para >
74
+ (In practice, we'd just name the aggregate "sum", and rely on
75
+ <productname >Postgres</productname > to figure out which kind
76
+ of sum to apply to a complex column.)
77
+ </para >
78
78
79
- <Para >
80
- If we define only <Acronym >sfunc2</Acronym >, we are
81
- specifying an aggregate
82
- that computes a running function that is independent of
83
- the attribute values from each instance.
84
- "Count" is the most common example of this kind of
85
- aggregate. "Count" starts at zero and adds one to its
86
- running total for each instance, ignoring the instance
87
- value. Here, we use the built-in
88
- <Acronym >int4inc</Acronym > routine to do
89
- the work for us. This routine increments (adds one to)
90
- its argument.
91
-
92
- <ProgramListing >
79
+ <para >
80
+ If we define only <acronym >sfunc2</acronym >, we are
81
+ specifying an aggregate
82
+ that computes a running function that is independent of
83
+ the attribute values from each instance.
84
+ "Count" is the most common example of this kind of
85
+ aggregate. "Count" starts at zero and adds one to its
86
+ running total for each instance, ignoring the instance
87
+ value. Here, we use the built-in
88
+ <acronym >int4inc</acronym > routine to do
89
+ the work for us. This routine increments (adds one to)
90
+ its argument.
91
+
92
+ <programlisting >
93
93
CREATE AGGREGATE my_count (
94
94
sfunc2 = int4inc, -- add one
95
95
basetype = int4,
@@ -104,21 +104,22 @@ SELECT my_count(*) as emp_count from EMP;
104
104
+----------+
105
105
|5 |
106
106
+----------+
107
- </ProgramListing>
108
- </Para>
109
-
110
- <Para>
111
- "Average" is an example of an aggregate that requires
112
- both a function to compute the running sum and a function
113
- to compute the running count. When all of the
114
- instances have been processed, the final answer for the
115
- aggregate is the running sum divided by the running
116
- count. We use the <Acronym>int4pl</Acronym> and <Acronym>int4inc</Acronym> routines we used
117
- before as well as the <ProductName>Postgres</ProductName> integer division
118
- routine, <Acronym>int4div</Acronym>, to compute the division of the sum by
119
- the count.
120
-
121
- <ProgramListing>
107
+ </programlisting>
108
+ </para>
109
+
110
+ <para>
111
+ "Average" is an example of an aggregate that requires
112
+ both a function to compute the running sum and a function
113
+ to compute the running count. When all of the
114
+ instances have been processed, the final answer for the
115
+ aggregate is the running sum divided by the running
116
+ count. We use the <acronym>int4pl</acronym> and
117
+ <acronym>int4inc</acronym> routines we used
118
+ before as well as the <productname>Postgres</productname> integer division
119
+ routine, <acronym>int4div</acronym>, to compute the division of the sum by
120
+ the count.
121
+
122
+ <programlisting>
122
123
CREATE AGGREGATE my_average (
123
124
sfunc1 = int4pl, -- sum
124
125
basetype = int4,
@@ -137,12 +138,34 @@ SELECT my_average(salary) as emp_average FROM EMP;
137
138
+------------+
138
139
|1640 |
139
140
+------------+
140
- </ProgramListing >
141
- </Para >
141
+ </programlisting >
142
+ </para >
142
143
143
- <Para>
144
- For further details see
145
- <xref endterm="sql-createaggregate-title"
146
- linkend="sql-createaggregate-title">.
147
- </Para>
148
- </Chapter>
144
+ <para>
145
+ For further details see
146
+ <!--
147
+ Not available in the Programmer's Guide
148
+ <xref endterm="sql-createaggregate-title"
149
+ linkend="sql-createaggregate-title">.
150
+ -->
151
+ <command>CREATE AGGREGATE</command> in
152
+ <citetitle>The PostgreSQL User's Guide</citetitle>.
153
+ </para>
154
+ </chapter>
155
+
156
+ <!-- Keep this comment at the end of the file
157
+ Local variables:
158
+ mode:sgml
159
+ sgml-omittag:nil
160
+ sgml-shorttag:t
161
+ sgml-minimize-attributes:nil
162
+ sgml-always-quote-attributes:t
163
+ sgml-indent-step:1
164
+ sgml-indent-data:t
165
+ sgml-parent-document:nil
166
+ sgml-default-dtd-file:"./reference.ced"
167
+ sgml-exposed-tags:nil
168
+ sgml-local-catalogs:("/usr/lib/sgml/catalog")
169
+ sgml-local-ecat-files:nil
170
+ End:
171
+ -->
0 commit comments