尝试在PostgreSQL中创建聚合函数
我正在尝试在PostgreSQL中创建新的聚合函数来代替尝试在PostgreSQL中创建聚合函数,postgresql,aggregate-functions,plpgsql,Postgresql,Aggregate Functions,Plpgsql,我正在尝试在PostgreSQL中创建新的聚合函数来代替sum()函数 我在手册中开始了我的旅程 因为我想创建一个函数,它接受一个双精度值数组,求和,然后进行一些额外的计算,我首先创建了最后一个函数: takes double precision as input and gives double precision as output DECLARE v double precision; BEGIN IF tax > 256 THEN
sum()
函数
我在手册中开始了我的旅程
因为我想创建一个函数,它接受一个双精度值数组,求和,然后进行一些额外的计算,我首先创建了最后一个函数:
takes double precision as input and gives double precision as output
DECLARE
v double precision;
BEGIN
IF tax > 256 THEN
v := 256;
ELSE
v := tax;
END IF;
RETURN v*0.21/0.79;
END;
然后,我想创建一个聚合函数,该函数接受一个双精度值数组,并输出一个双精度值供上一个函数处理
CREATE AGGREGATE aggregate_ee_income_tax (float8[]) (
sfunc = array_agg
,stype = float8
,initcond = '{}'
,finalfunc = eeincometax);
运行该命令时得到的结果是:
错误:函数数组_agg(双精度,双精度[])不存在
不存在
我有点被困在这里,因为手册列出了现有的功能。我做错了什么
此外,当我跑步时:
\da
List of aggregate functions
Schema | Name | Result data type | Argument data types | Description
--------+------+------------------+---------------------+-------------
(0 rows)
我的安装根本没有聚合功能?还是只列出用户定义的函数
基本上我想了解的是:
1) 我是否可以使用现有函数对数组值求和
2) 如何了解函数的输入和输出数据类型?文档声称array\u agg()
接受任何类型的输入
3) 我自己的聚合函数有什么问题
编辑1
为了提供更多信息并更清楚地了解我正在努力实现的目标:
我对几个表进行了一个巨大的查询,查询结果如下:
SELECT sum(tax) ... from (SUBQUERY) as foo group by id
我想用我自己的聚合函数替换那个求和函数,这样我就不必在后端进行额外的计算——因为它们都可以在数据库级别上完成
编辑2
我接受了蚂蚁的回答。由于最终解决方案来自评论,我将其发布在此处以供参考:
CREATE AGGREGATE aggregate_ee_income_tax (float8)
(
sfunc = float8pl
,stype = float8
,initcond = '0.0'
,finalfunc = eeincometax
);
数组agg是聚合函数而不是常规函数,因此它不能用作新聚合的状态转换函数。您要做的是创建一个聚合函数,它有一个与array_agg相同的状态转换函数和一个自定义final函数 不幸的是,array_agg的状态转换函数是根据内部数据类型定义的,因此不能重用。幸运的是,core中已有一个函数,它已经完成了您想要的功能
CREATE AGGREGATE aggregate_ee_income_tax (float8)(
sfunc = array_append,
stype = float8[],
initcond = '{}',
finalfunc = eeincometax);
还请注意,您的类型混淆了,您可能希望将一组浮点聚合到一个数组,而不是将一组数组聚合到一个浮点。除了@Ants极好的建议: 1.)您的最终功能可以简化为:
CREATE FUNCTION eeincometax(float8)
RETURNS float8 LANGUAGE SQL AS
$func$
SELECT (least($1, 256) * 21) / 79
$func$;
2)你好像在和钱打交道?在这种情况下,我强烈建议使用类型(首选)或用于此目的。浮点运算通常不够精确
3.)骨料的初始条件可以仅为0
:
CREATE AGGREGATE aggregate_ee_income_tax(float8)
(
sfunc = float8pl
,stype = float8
,initcond = 0
,finalfunc = eeincometax
);
4.)在您的情况下,
(最少(总和(税),256)*21)/79
可能比您的自定义聚合快。PostgreSQL提供的聚合函数是用C编写的,并针对性能进行了优化。我会用它来代替。太棒了。这让我更接近我想要的,但eeincometax finalfunc期望的是单个float8值,而不是数组。而array_append似乎只是输出数组。所以我仍然需要在finalfunction中进行实际的求和,或者有输出单个值的核心函数吗?因此,作为状态转换,需要一个函数,它接受两个浮点并返回它们的和。巧合的是,+操作符就是这么做的。为float8实现+运算符的函数称为float8pl。将sfunc更改为float8pl,将stype更改为float8,您应该是golden。不,我需要一个聚合函数,该函数接受一堆记录并对它们求和,然后将该和作为输入提供给finalfunc。就像我说的-我希望函数可以替换查询中的sum()函数。是的,这就是它要做的。作为转换函数的float8pl将值求和,并将最终值传递给func。我还忘了提到您需要将initcond更改为0.0.0。至少我没有犯错误地完成了一切。但价值产出似乎是错误的。我现在正在调试:)。从您的描述中,我不明白为什么不能使用yourfinalfunc(sum(tax))
来转换最终结果?这将避免完全创建聚合函数。因为我提到的查询是通过编程方式组合在一起的,如果我要在另一个函数上添加一个函数,那么在组合查询的过程中,我必须做很多更改。添加大量的条件和诸如此类的东西——所有这些都会使以后理解代码变得更加困难。因此,只需更改求和函数就更容易了。感谢提供更多信息。不过,这只是一个问题——因为我的自定义聚合函数依赖于postgreSQL自己的float8pl函数,正如我从您的帖子中了解到的,它也是用C编写并优化的——我的函数实际增加了多少开销?@Zayatzz:最好只是测试一下。运行两个变体-可能几次以排除缓存效果。我对比较感兴趣。。。