在PostgreSQL中编写自己的聚合函数

use*_*882 4 sql postgresql aggregate-functions

我从不修改自己的集合,只存储过程,我需要一些建议。我想编写一个自定义聚合,该聚合将返回整数行的最大值并将其递增10。我该怎么做?我尝试了这个:

CREATE AGGREGATE incremented_max ( v ) (
    SFUNC = max,
    STYPE = integer,
    INITCOND = max + 10
)
Run Code Online (Sandbox Code Playgroud)

但这没用。有人可以帮我吗?

我得到了错误:

ERROR:  syntax error at or near "+"
LINE 4:     INITCOND = max + 10
Run Code Online (Sandbox Code Playgroud)

老实说,我不知道它应该如何工作。

kli*_*lin 6

理查德的答案与问题无关。您要求max()+10不要sum()+10

以下示例显示如何使用自定义函数创建聚合:

create function greaterint (int, int)
returns int language sql
as $$
    select case when $1 < $2 then $2 else $1 end
$$;

create function intplus10 (int)
returns int language sql
as $$
    select $1+ 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
Run Code Online (Sandbox Code Playgroud)

Sfunc是一个state transition function。聚合执行的次数与要聚合的行数相同。它的第一个参数是internal-state,即到目前为止累积的值。在第一个调用中,该值等于initcond(或null如果initcond未定义)。第二个参数是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)
Run Code Online (Sandbox Code Playgroud)

Finalfunc在聚合结束时执行一次。它有一个参数(到目前为止计算出的值),并返回聚合的最终(修改后的)结果。在我们的示例中,它仅将10加到聚合结果中。

文档中阅读更多内容

上面的示例只是一种练习。实际上,由于select max (v + 10)给出了期望的结果,因此无需定义此类汇总。