必要なことを実行するstring_agg()が組み込まれていますが、MySQLとの互換性のためにgroup_concatという名前を付けるように特に要求します。残念ながら、string_agg()は累積に内部データ型を使用し(おそらく、各追加でバッファー全体をコピーすることを避けるために、ソースを調べていません)、string_agg(と同じSQLアグリゲートを宣言する方法が見つかりませんでした)。 。
group_concat()関数の定義も機能しません。これは、pgが集約であり、内部に集約が隠されている関数ではなく、機能しないことをpgに認識させる必要があるためです。このような関数は、一度に1つの行で動作します。内部の集計は、1つの行を集計し、変更せずに返します...
したがって、このコードは要素を配列に累積し、array_to_stringで「、」区切り文字を追加します。 array_agg()宣言(組み込みになる前)をモデルとして使用し、集約された配列をテキストに変換するファイナライザー関数を追加するだけです。
CREATE OR REPLACE FUNCTION _group_concat_finalize(anyarray)
RETURNS text AS $$
SELECT array_to_string($1,',')
$$ IMMUTABLE LANGUAGE SQL;
CREATE AGGREGATE group_concat(anyelement) (
SFUNC=array_append,
STYPE=anyarray,
FFUNC=_group_concat_finalize,
INITCOND='{}'
);
SELECT group_concat(x) FROM foo;
良い点は、ジェネリック型「anyarray」と「anyelement」のおかげで、面倒なことなく、どの型でも問題なく動作するはずです。
string_aggが各追加で集計配列全体をコピーすることを実際に回避する場合、これはstring_agg()よりも遅くなると思います。ただし、これは、各セットにグループ化される行の数が多い場合にのみ問題になります。この場合、SQLクエリの編集に1分を費やすことができます;)
http://sqlfiddle.com/#!17/c452d/1