九月 20, 2024
摘要:在本教程中,您将学习如何在 PostgreSQL 中创建自己的聚合函数。
目录
聚合函数的基础知识
这些不错的函数可以支持您聚合一个表的多行。假设您有一个名为 employees 的表,有一个列 salary,并且您想要获得所有 salary 的总和。您可以手动求和(当然只是玩笑),也可以使用标准的聚合函数(如 SUM),该函数对找到的每个数据集执行运算,从而计算出总和。
要使用标准化的聚合函数,您可以这样做:
SELECT SUM(salary) AS total_sum FROM employees;
那么,这个 sum 运算需要做些什么呢?聚合函数的最大优点是,它们可以组合多行,而不是最大组合列。在我们的示例中,SUM 操作对所有 salary 求和,这些 salary 是查询行的一部分。除了聚合函数之外,没有其他方法可以归入行,除非您在应用程序方面处理一些事情。
PostgreSQL 的一大优势是您可以创建自定义的聚合函数,从而满足您想要的组合计算。
快速开始
在阅读本段之前,请预先查看有关 CREATE AGGREGATE 的官方文档。基于此,这里会尝试解释下关键要点,并在最重要的步骤中为您提供帮助。
CREATE AGGREGATE 的概要如下:
CREATE AGGREGATE name ( input_data_type [ , ... ] ) (
SFUNC = sfunc,
STYPE = state_data_type
[ , FINALFUNC = ffunc ]
[ , INITCOND = initial_condition ]
[ , SORTOP = sort_operator ]
)
想象一下 AGGREGATE 是一个流程,它有一个定义的状态(STYPE 类型,稍后会详细介绍),该状态在遍历所选的数据集期间会发生变化。具体将更改的内容,是通过函数 SFUNC 定义的。最终函数 FINALFUNC 将在聚合后应用,其返回值将作为聚合的结果返回 - FINALFUNC 的默认行为是返回最后一个已知状态。
为了补充官方文档,这里为您查找正确值提供一些提示。
-
STYPE:数据类型,聚合器以该类型来记录其当前状态。此状态(类型 STYPE)将作为第一个参数,传递给函数 SFUNC。
-
SFUNC:函数的名称,需要 (state_data_type, input_data_type(s)) 作为参数,并返回 STYPE 类型的值。
SFUNC(state<STYPE>, next input_data_type(s)) ---> new state<STYPE>
要获取所有可用函数的列表,请使用 psql 连接,键入 \df <begin_of_expression>,并按 <Tab>(类似于 Unix 自动完成)。如果按下 <Enter>,将显示有关该函数的详细信息。
要列出可用的函数 (SFUNC),可执行以下操作:
testdb=> \df ip4 ip4 ip4_in ip4_and ip4_le ip4_cmp ip4_xor [...] testdb=> \df ip4_xor schema | name | result data type | argument data types --------+---------+------------------+-------------------- public | ip4_xor | ip4 | ip4, ip4
有关更多详细信息,您可以查看 PostgreSQL 系统表 pg_proc。
-
FINALFUNC:内部聚合器的最后一个状态(聚合后)与聚合返回值之间的连接器。可以对最后一个状态值做强制转换,还可以对其执行最终的操作。
FINALFUNC(state<STYPE>) ---> aggregator return value
-
INITCOND:内部状态的起始值。强烈建议您声明这一点。
示例
假设我们在创建自定义聚合函数时,有一个表,其中有许多包含了 IP 地址的数据集。一个简单的想法是,构建一个所有 IP 地址的哈希码,来对数据集进行校验,这可以通过对所有 IP 地址进行 XOR 来轻松完成。
最后,您可以定义用于“哈希” IPv4 地址的聚合器,如下所示:
01 CREATE AGGREGATE hash_ips ( ip4 ) (
02 SFUNC = ip4_xor,
03 STYPE = ip4,
04 INITCOND = '0.0.0.0'
05 )
描述:
聚合器称为 hash_ips(第 1 行),它需要一个 ip4 类型的参数(第 1 行,有关 ip4 的更多信息,请查看项目)。它的初始状态本身也是 ip4 类型(第 3 行),初始值为 IP 地址 0.0.0.0(第 4 行)。对于每个数据集,将其进行 XOR 运算(通过传递函数 ip4_xor,第 2 行),并将在迭代后返回(因为未声明 FINALFUNC)。
在创建后,您可以像其他聚合函数一样使用该聚合函数:
SELECT hash_ips(column_with_ip) FROM mytable;
有关更多示例,请查看官方示例。
了解更多
PostgreSQL 文档:CREATE AGGREGATE
PostgreSQL 教程:聚合函数