CREATE AGGREGATE
CREATE AGGREGATE — 定义一个新的聚合函数
大纲
CREATE AGGREGATEname( BASETYPE =input_data_type[ , SFUNC1 =sfunc1, STYPE1 =state1_type] [ , SFUNC2 =sfunc2, STYPE2 =state2_type] [ , FINALFUNC =ffunc] [ , INITCOND1 =initial_condition1] [ , INITCOND2 =initial_condition2] )
输入
name要创建的聚合函数的名称。
input_data_type此聚合函数所操作的输入数据类型。
sfunc1一个状态转移函数,会为每个非 NULL 输入数据值调用。它必须是一个双参数函数,第一个参数的类型为
state1_type,第二个参数的类型为input_data_type。该函数必须返回state1_type类型的值。此函数接受当前状态值 1 和当前输入数据项,并返回下一个状态值 1。state1_type聚合的第一个状态值的数据类型。
sfunc2一个状态转移函数,会为每个非 NULL 输入数据值调用。它必须是一个单参数函数,参数类型为
state2_type,返回同一类型的值。此函数接受当前状态值 2,并返回下一个状态值 2。state2_type聚合的第二个状态值的数据类型。
ffunc在遍历完所有输入数据之后调用的、用于计算聚合结果的最终函数。如果使用了两个状态值,最终函数必须接受两个参数,类型分别为
state1_type和state2_type。如果只使用了一个状态值,最终函数必须接受单个该状态值类型的参数。聚合的输出数据类型被定义为该函数的返回类型。initial_condition1状态值 1 的初始值。
initial_condition2状态值 2 的初始值。
输出
CREATE命令成功完成时返回的消息。
描述
CREATE AGGREGATE
允许用户或程序员通过定义新的聚合函数来扩展 Postgres
的功能。基本发行版中已经提供了一些针对基本类型的聚合函数,例如min(int4)
和avg(float8)。如果定义了新的类型,或者需要一个尚未提供的聚合函数,就可以使用CREATE AGGREGATE
来提供所需的功能。
聚合函数由其名称和输入数据类型标识。两个聚合如果操作于不同的输入类型,则可以有相同的名称。为避免混淆,不要创建与某个聚合同名且具有相同输入数据类型的普通函数。
一个聚合函数由一到三个普通函数构成:两个状态转移函数,sfunc1
和 sfunc2,以及一个最终计算函数,ffunc。它们的用法如下:
sfunc1( internal-state1, next-data-item ) ---> next-internal-state1sfunc2( internal-state2 ) ---> next-internal-state2ffunc(internal-state1, internal-state2) ---> aggregate-value
Postgres 会创建一个或两个临时变量(数据类型为 stype1 和/或
stype2),用来保存聚合的当前内部状态。对于每个输入数据项,都会调用状态转移函数来为内部状态值计算新值。等到所有数据都处理完毕后,再调用一次最终函数来计算聚合的输出值。
如果两个转移函数都指定了,那么必须指定
ffunc。如果只使用一个转移函数,那么 ffunc 是可选的。未提供
ffunc 时的默认行为是返回所使用的内部状态值的结束值(因此聚合的输出类型与该状态值的类型相同)。
聚合函数还可以提供一个或两个初始条件,即所使用的内部状态值的初始值。它们在数据库中以
text类型的字段的形式指定和存储,但它们必须是状态值数据类型常量的合法外部表示。如果指定了 sfunc1
而没有指定 initcond1 值,那么系统不会在第一个输入项上调用 sfunc1;而是用第一个输入值初始化内部状态值 1,并从第二个输入项开始调用
sfunc1。这对于 MIN 和
MAX 这类聚合很有用。注意,使用这一特性的聚合在没有输入值时被调用会返回 NULL。对状态值 2 没有类似的机制;如果指定了 sfunc2,那么就需要一个 initcond2。
注意
使用DROP AGGREGATE
删除聚合函数。
CREATE AGGREGATE的参数可以按任意顺序书写,而不只是按上面展示的顺序。
可以指定具有不同状态函数和最终函数组合的聚合函数。例如,count聚合需要
sfunc2(一个递增函数)但不需要
sfunc1 或
ffunc;而 sum聚合需要
sfunc1(一个加法函数)但不需要 sfunc2 或
ffunc;而
avg
聚合则需要两个状态函数以及一个 ffunc(一个除法函数)来产生它的结果。无论如何,至少要定义一个状态函数,而且任何
sfunc2 都必须有一个对应的
initcond2。
用法
完整的使用示例请参阅PostgreSQL 程序员指南中关于聚合函数的章节。
兼容性
SQL92
CREATE AGGREGATE
是 Postgres 的语言扩展。SQL92 中没有CREATE AGGREGATE。