CREATE AGGREGATE
CREATE AGGREGATE — 定义一个新的聚合函数
大纲
CREATE AGGREGATEname( BASETYPE =input_data_type, SFUNC =sfunc, STYPE =state_data_type[ , FINALFUNC =ffunc] [ , INITCOND =initial_condition] [ , SORTOP =sort_operator] )
描述
CREATE AGGREGATE 定义一个新的聚合函数。系统自带了一些基本且常用的聚合函数;它们在第 9.15 节中有文档说明。如果需要定义新类型或需要一个尚未提供的聚合函数,则可以使用 CREATE AGGREGATE 来实现所需功能。
如果给出了一个模式名(例如CREATE AGGREGATE
myschema.myagg ...),则该聚合函数会在指定模式中创建。否则会在当前模式中创建。
聚合函数由其名称和输入数据类型标识。同一模式中的两个聚合如果操作于不同的输入类型,则可以有相同的名称。聚合的名称和输入数据类型还必须与同一模式中每个普通函数的名称和输入数据类型都不同。
一个聚合函数由一个或两个普通函数构成:一个状态转移函数sfunc,以及一个可选的最终计算函数ffunc。它们的用法如下:
sfunc( internal-state, next-data-item ) ---> next-internal-stateffunc( internal-state ) ---> aggregate-value
PostgreSQL会创建一个数据类型为
stype的临时变量,用来保存聚合的当前内部状态。对于每个输入数据项,都会调用状态转移函数来计算新的内部状态值。等到所有数据处理完毕后,再调用一次最终函数来计算聚合的返回值。如果没有最终函数,则原样返回结束时的状态值。
聚合函数可以提供一个初始条件,即内部状态值的初始值。它在数据库中以
text类型的列指定和存储,但它必须是该状态值数据类型常量的合法外部表示。如果未提供,则状态值初始为空值。
如果状态转移函数被声明为“strict”的,那么它不能以空值输入被调用。使用这种转移函数时,聚合的执行行为如下:空值输入会被忽略(不调用函数并保留先前的状态值)。如果初始状态值为空,那么第一个非空输入值会取代状态值,而转移函数会从第二个非空输入值开始被调用。这对于实现max这类聚合很方便。注意,只有当state_data_type与第一个input_data_type相同时,此行为才可用。当这两种类型不同时,必须提供非空的初始条件或者使用非严格的转移函数。
如果状态转移函数不是严格的,那么它会在每个输入值上被无条件调用,并且必须自行处理空值输入和空值转移值。这使聚合作者能完全控制聚合对空值的处理。
如果最终函数被声明为“strict”,那么当结束状态值为空时不会调用它;而是自动返回空结果。(这当然只是 strict 函数的正常行为。)无论如何,最终函数都可以选择返回空值。例如,avg的最终函数在发现输入行数为零时会返回空值。
行为类似于MIN或MAX的聚合,有时可以通过查阅索引而不是扫描每个输入行来优化。如果该聚合可以这样优化,请通过指定一个排序操作符来表明。基本要求是,该聚合必须返回该操作符所诱导的排序顺序中的第一个元素;换句话说:
SELECT agg(col) FROM tab;
必须等价于
SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
进一步的假设是,该聚合忽略空输入,并且当且仅当不存在非空输入时返回空结果。通常,某种数据类型的<操作符是
MIN的合适排序操作符,而>是
MAX的合适排序操作符。注意,除非指定的操作符是
B-树索引操作符类中“小于”或“大于”策略成员,否则这种优化实际上永远不会生效。
参数
name要创建的聚合函数的名称(可带模式限定)。
input_data_type此聚合函数所操作的输入数据类型。对于不检查其输入值的聚合(例如
count(*)),可以将其指定为"ANY"。sfunc要为每个输入数据值调用的状态转移函数的名称。它通常是一个两参数函数,第一个参数的类型为
state_data_type,第二个的类型为input_data_type。或者,对于不检查其输入值的聚合,该函数只接受一个类型为state_data_type的参数。无论哪种情况,该函数都必须返回state_data_type类型的值。此函数接受当前状态值和当前输入数据项,并返回下一个状态值。state_data_type聚合状态值的数据类型。
ffunc在遍历完所有输入数据之后调用的、用于计算聚合结果的最终函数的名称。该函数必须接受单个类型为
state_data_type的参数。聚合的返回数据类型被定义为该函数的返回类型。如果没有指定ffunc,则结束状态值被用作聚合的结果,返回类型为state_data_type。initial_condition状态值的初始设置。这必须是
state_data_type数据类型所接受形式的字符串常量。如果未指定,状态值将从 null 开始。sort_operator类
MIN或MAX聚合的关联排序操作符。这只是一个操作符名称(可以用模式限定)。假定该操作符具有与聚合相同的输入数据类型。
CREATE AGGREGATE的参数可以按任意顺序书写,而不只是按上面展示的顺序。
示例
兼容性
CREATE AGGREGATE是
PostgreSQL的语言扩展。SQL 标准不提供用户定义聚合函数。