在 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) 给出了想要的结果。