在 postgresql 中编写我自己的聚合函数
Writing my own aggregate function in postgresql
我从来没有写过自己的集合,只写过存储过程,我需要一些建议。
我想编写一个自定义聚合,它将达到 return 整数行的最大值并将其增加 10。我该怎么做?我试过这个:
CREATE AGGREGATE incremented_max ( v ) (
SFUNC = max,
STYPE = integer,
INITCOND = max + 10
)
但是没用。有人可以帮我吗?
我收到错误:
ERROR: syntax error at or near "+"
LINE 4: INITCOND = max + 10
老实说,我不明白它应该如何工作。
BEGIN;
CREATE AGGREGATE inc_sum(int) (
sfunc = int4pl,
stype = int,
initcond = 10
);
CREATE TEMP TABLE tt (i int);
INSERT INTO tt VALUES (1),(2),(3),(4);
SELECT sum(i), inc_sum(i) FROM tt;
ROLLBACK;
sum | inc_sum
-----+---------
10 | 20
(1 row)
上面的int4pl是"+"的底层函数(通过列出以int开头的函数然后猜测找到的)
initcond 是初始条件,所以你从哪里开始。对于 0 的正常总和。
以下示例展示了如何使用自定义函数创建聚合:
create function greaterint (int, int)
returns int language sql
as $$
select case when < then else end
$$;
create function intplus10 (int)
returns int language sql
as $$
select + 10;
$$;
create aggregate incremented_max (int) (
sfunc = greaterint,
finalfunc = intplus10,
stype = integer,
initcond = 0
);
select incremented_max(v), max(V)
from (
select 3 as v
union select 10
union select 12
union select 5) alias
Sfunc
是一个状态转换函数。它在聚合中执行的次数与要聚合的行数一样多。它的第一个参数是 internal-state
,即到目前为止累积的值。在第一次调用中,该值等于 initcond
(如果未定义 initcond
,则等于 null
)。第二个参数是 next-data-value
,即下一行的值。在上面的示例中,函数计算非空正整数的最大值并执行四次(四行):
call # internal-state next-data-value result
1 0 (initcond) 3 3 (because 3 > 0)
2 3 10 10 (10 > 3)
3 10 12 12 (12 > 10)
4 12 5 12 (12 > 5)
Finalfunc 在聚合结束时执行一次。它有一个参数(到目前为止计算的值)和 returns 聚合的最终(修改后的)结果。在我们的示例中,它只是将聚合结果加 10。
在 documentation 阅读更多内容。
上面的例子只是一种练习。事实上,没有必要定义这样的聚合,因为 select max (v + 10)
给出了想要的结果。
我从来没有写过自己的集合,只写过存储过程,我需要一些建议。 我想编写一个自定义聚合,它将达到 return 整数行的最大值并将其增加 10。我该怎么做?我试过这个:
CREATE AGGREGATE incremented_max ( v ) (
SFUNC = max,
STYPE = integer,
INITCOND = max + 10
)
但是没用。有人可以帮我吗?
我收到错误:
ERROR: syntax error at or near "+"
LINE 4: INITCOND = max + 10
老实说,我不明白它应该如何工作。
BEGIN;
CREATE AGGREGATE inc_sum(int) (
sfunc = int4pl,
stype = int,
initcond = 10
);
CREATE TEMP TABLE tt (i int);
INSERT INTO tt VALUES (1),(2),(3),(4);
SELECT sum(i), inc_sum(i) FROM tt;
ROLLBACK;
sum | inc_sum
-----+---------
10 | 20
(1 row)
上面的int4pl是"+"的底层函数(通过列出以int开头的函数然后猜测找到的)
initcond 是初始条件,所以你从哪里开始。对于 0 的正常总和。
以下示例展示了如何使用自定义函数创建聚合:
create function greaterint (int, int)
returns int language sql
as $$
select case when < then else end
$$;
create function intplus10 (int)
returns int language sql
as $$
select + 10;
$$;
create aggregate incremented_max (int) (
sfunc = greaterint,
finalfunc = intplus10,
stype = integer,
initcond = 0
);
select incremented_max(v), max(V)
from (
select 3 as v
union select 10
union select 12
union select 5) alias
Sfunc
是一个状态转换函数。它在聚合中执行的次数与要聚合的行数一样多。它的第一个参数是 internal-state
,即到目前为止累积的值。在第一次调用中,该值等于 initcond
(如果未定义 initcond
,则等于 null
)。第二个参数是 next-data-value
,即下一行的值。在上面的示例中,函数计算非空正整数的最大值并执行四次(四行):
call # internal-state next-data-value result
1 0 (initcond) 3 3 (because 3 > 0)
2 3 10 10 (10 > 3)
3 10 12 12 (12 > 10)
4 12 5 12 (12 > 5)
Finalfunc 在聚合结束时执行一次。它有一个参数(到目前为止计算的值)和 returns 聚合的最终(修改后的)结果。在我们的示例中,它只是将聚合结果加 10。
在 documentation 阅读更多内容。
上面的例子只是一种练习。事实上,没有必要定义这样的聚合,因为 select max (v + 10)
给出了想要的结果。