Postgresql

是否可以在 Postgres 中包裝聚合函式?

  • September 26, 2012

Postgres 的 string_agg(expr, delimiter) 函式很棒。但我希望有一個版本,它採用單個參數 - 要聚合的欄位 - 並假設分隔符為 ‘, ‘,因為這是我想要的 9 次(10 次)。使用非聚合函式,我可以只需這樣做:

create or replace function public.string_agg(text)
returns text
as $$
   select string_agg($1, ', ');
$$ language sql
immutable;

但是由於 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$;

匯總:

CREATE AGGREGATE f_str_agg (anyelement) (
   SFUNC     = array_append
  ,STYPE     = anyarray
  ,INITCOND  = '{}'
  ,FINALFUNC = f_str_agg_final
);

稱呼:

SELECT f_str_agg (kat) from tbl;

適用於幾乎任何類型 - 除了數組類型。您將不得不為此修改您的聚合。更多關於 SO 的密切相關的答案

引用自:https://dba.stackexchange.com/questions/24984