CREATE AGGREGATE name ( BASETYPE = input_data_type, SFUNC = sfunc, STYPE = state_type [ , FINALFUNC = ffunc ] [ , INITCOND = initial_condition ] )
要创建的聚集函数名.
本聚集函数要处理的基本数据类型. 对于不检查输入类型的聚集来说,这个参数可以声明为 ANY. (比如 count(*)).
用于处理源数据列里的每一个输入数据的状态转换函数名称. 它通常是一个两个参数的函数,第一个参数的类型是 state_type 而第二个参数的类型是 input_data_type. 另外,对于一个不检查输入数据的聚集,该函数只接受一个类型为 state_type 的参数. 不管是哪种情况,此函数必须返回一个类型为 state_type的值. 这个函数接受当前状态值和当前输入数据条目,而返回下个状态值.
聚集的状态值的数据类型.
在转换完所有输入域/字段后调用的最终处理函数.它计算聚集的结果. 此函数必须接受一个类型为 state_type 的参数. 聚集的输出数据类型被定义为此函数的返回类型. 如果没有声明 ffunc 则使用聚集结果的状态值作为聚集的结果,而输出类型为 state_type.
状态值的初始设置(值).它必须是一个数据类型 state_type 可以接受的文本常量值. 如果没有声明,状态值初始为 NULL.
CREATE AGGREGATE 允许用户或程序员通过定义新的聚集函数来扩展 Postgres 的功能.一些用于基本类型的聚集函数如 min(integer) 和 avg(double precision) 等已经包含在基础软件包里了. 如果你需要定义一个新类型或需要一个还没有提供的聚集函数,这时便可用 CREATE AGGREGATE 来提供我们所需要的特性.
一个聚集函数是用它的名字和输入数据类型来标识的. 如果两个聚集的输入数据不同,它们可以有相同的名字.要避免冲突, 不要写一个与聚集同名而且输入函数也相同的普通函数.
一个聚集函数是用一个或两个普通函数做成的: 一个状态转换函数 sfunc, 和一个可选的终计算函数 ffunc. 它们是这样使用的:
sfunc( internal-state, next-data-item ) ---> next-internal-state ffunc( internal-state ) ---> aggregate-value
Postgres 创建一个类型为 stype的临时变量. 它保存这个聚集的当前内部状态. 对于每个输入数据条目, 都调用状态转换函数计算内部状态值的新数值. 在处理完所有数据后,调用一次最终处理函数以计算聚集的输出值. 如果没有最终处理函数,那么将最后的状态值当做返回值.
一个聚集函数还可能提供一个初始条件,也就是说, 所用的该内部状态值的初始值.这个值是作为类型 text 的数据域存储在数据库里的, 不过它们必须是状态值数据类型的合法的外部表现形式的常量. 如果没有提供状态,那么状态值初始化为 NULL.
如果在 pg_proc 里该状态转换函数被定义为 "strict", 那么 NULL 输入就不能调用它.这个时候,带有这样的转换函数的聚集执行 起来的现象如下所述.NULL 输入的值被忽略(不调用此函数并且保留前一个 状态值).如果初始状态值是 NULL,那么由第一个非 NULL 值替换该状态值, 而状态转换函数从第二个非 NULL 的输入值开始调用.这样做让我们比较容易 实现象 max 这样的聚集. 请注意这种行为只是当 state_type 与 input_data_type 相同的时候才表现出来. 如果这些类型不同,你必须提供一个非 NULL 的初始条件或者使用一个 非strice的状态转换函数.
如果状态转换函数不是 strict(严格)的, 那么它将无条件地为每个输入值调用, 并且必须自行处理 NULL 输入和 NULL 转换值, 这样就允许聚集的作者对聚集中的 NULL 有完全的控制.
如果终转换函数定义为"strict",则如果最终状态值是 NULL 时就不能调用它; 而是自动输出一个NULL的结果.(当然,这才是 strict 函数的正常特征.) 不管是那种情况,终处理函数可以选择返回 NULL.比如, avg 的终处理函数在零输入记录时就会返回 NULL.