Noa*_*ter 7 postgresql aggregate functions
Postgres 的 string_agg(expr, delimiter) 函数很棒。但我想要一个版本,它接受一个参数——要聚合的字段——并假设分隔符为 ', ' 因为这是我想要的 10 次中的 9 次。使用非聚合函数,我可以只需这样做:
create or replace function public.string_agg(text)
returns text
as $$
select string_agg($1, ', ');
$$ language sql
immutable;
Run Code Online (Sandbox Code Playgroud)
但由于 string_agg 是一个聚合函数,这不起作用。它抱怨我传递给它的字段需要在 GROUP BY 子句中,这告诉我查询引擎不知道我的包装器是一个聚合函数。
我查看了用户定义聚合的文档(http://www.postgresql.org/docs/9.1/static/xaggr.html 和http://www.postgresql.org/docs/9.1/static/sql-createaggregate .html ) 但我不清楚如何使用现有的 string_agg(text, text) 定义我的新 string_agg(text)。看来我必须从头开始定义我的新函数,这比我想承担的要复杂得多,而且我也不完全有信心我可以完美地反映内置 string_agg 的行为。
那么是否有一些技术可以创建一个我没有看到的简单包装器?或者我将不得不做更多的工作?
据我所知,您无法包装聚合函数。您必须编写自己的聚合函数。
如果您编写自己的函数,则在升级或移植到另一个数据库时可能会遇到不兼容的情况。因此,就我个人而言,我不会打扰,只需string_agg()在每次调用时添加分隔符即可。其实并没有那么痛苦。
也就是说,编写自己的聚合函数也不那么复杂:
自定义最终函数:
CREATE FUNCTION f_str_agg_final(anyarray)
RETURNS text LANGUAGE SQL AS
$func$SELECT array_to_string($1, ', ')$func$;
Run Code Online (Sandbox Code Playgroud)
总计:
CREATE AGGREGATE f_str_agg (anyelement) (
SFUNC = array_append
,STYPE = anyarray
,INITCOND = '{}'
,FINALFUNC = f_str_agg_final
);
Run Code Online (Sandbox Code Playgroud)
称呼:
SELECT f_str_agg (kat) from tbl;
Run Code Online (Sandbox Code Playgroud)
适用于几乎任何类型 - 除了数组类型。您必须为此修改您的聚合。更多内容请参见关于 SO 的密切相关答案。
| 归档时间: |
|
| 查看次数: |
1814 次 |
| 最近记录: |