如何向PostgreSQL添加自定义聚合函数(例如MAX / MIN)?

时间:2014-10-03 16:11:47

标签: postgresql aggregate

我想在Postgresql中添加一些扩展函数,比如max / min,但我找不到它们的源函数。任何人都可以建议我应该查看哪部分源代码?谢谢,

这是一个例子。我有关系:model(id int)其中model是一组CAD模型,每个模型都有一个ID;我想找到id> 5和area> 5的所有型号。但我不想计算所有面部区域,所以我使用having子句只计算一个子集。这是查询:

select model.id, model.face_number
from
    model
where
    id>5
group by model.id
having
    area(model.id)>5;

我想将函数区(oid)函数定义为max / min作为FDW。但我不知道如何传递输入参数,所以我想将它与min / max进行比较。

2 个答案:

答案 0 :(得分:3)

这没有多大意义。

minmax聚合函数。它们将一组行减少为单个值。

您的问题描述似乎与汇总无关。因此,总体而言,聚合函数与它无关。

如果您确实需要编写聚合函数,请从PostgreSQL手册开始:

我强烈建议您使用PL / PgSQL或其他过程语言对聚合函数进行原型设计。只有当您已经证明它可以使用更快速的工作语言工作时才能用C语言编写,并且确定您需要的速度比使用PL / PgSQL或PL / Python或其他任何方式更快。< / p>

无论如何,如果你想找到min / max的实现,请从这里开始:

select a.*, so.oprname as aggsortopname, tt.typname as aggtranstypename
from pg_aggregate a 
inner join pg_proc p on (a.aggfnoid = p.oid) 
inner join pg_type tt on (a.aggtranstype = tt.oid)
inner join pg_operator so on (a.aggsortop = so.oid)
where p.proname = 'max';

您将看到聚合由多个部分组成:转换函数排序运算符转换状态类型,一个可选的最终函数等。有关用户定义聚合的文档详细解释了这一点。

所以没有单一的&#34;最大功能&#34;。 maxpg_proc.h的定义实际上仅指虚拟函数。

因此,对于max(int4),它被定义为转换函数int4largersrc/backend/utils/adt/int.c)而不是转换类型int4,并且使用排序运算符> },没有最终功能。

答案 1 :(得分:0)

您不希望所描述内容的聚合函数。在你有一个工作版本之前,你也不应该担心性能 - 如果你写这个,PostgreSQL的查询优化器可能会完全符合你的要求:

select model.id, model.face_number
from
    model
where
    id>5 and area(model.id)>5;

这是一个示例函数:

CREATE FUNCTION area(int in_id)
RETURNS double precision AS $$
    SELECT length*width FROM model WHERE id=in_id;
$$ LANGUAGE SQL STABLE;

当然,您可以使用更合适的计算来替换length*width