Il existe une fonction intégrée string_agg() qui fait ce que vous voulez, mais vous demandez spécifiquement qu'elle soit nommée group_concat pour la compatibilité MySQL. Malheureusement, string_agg() utilise un type de données interne pour l'accumulation (probablement pour éviter de copier tout le tampon à chaque ajout, je n'ai pas regardé la source cependant) et je n'ai pas trouvé de moyen de déclarer un agrégat SQL identique à string_agg( ).
Définir la fonction group_concat() ne fonctionnerait pas non plus, car pg doit être conscient qu'il s'agit d'un agrégat, et non d'une fonction avec un agrégat caché à l'intérieur, ce qui ne fonctionnerait pas. Une telle fonction fonctionnerait sur une ligne à la fois :tout agrégat à l'intérieur ne ferait qu'agréger une seule ligne et la renverrait inchangée...
Ainsi, ce code accumulera les éléments dans un tableau, puis ajoutera les délimiteurs "," avec array_to_string. J'utiliserai la déclaration array_agg() (avant qu'elle ne devienne intégrée) comme modèle, et j'ajouterai simplement une fonction de finalisation qui convertira le tableau agrégé en texte.
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;
La bonne chose est que cela devrait fonctionner correctement pour n'importe quel type, sans tracas, grâce aux types génériques "anyarray" et "anyelement".
Je suppose que ce serait plus lent que string_agg() si string_agg évite effectivement de copier tout le tableau d'agrégation à chaque ajout. Cependant, cela ne devrait avoir d'importance que si le nombre de lignes à regrouper dans chaque ensemble est important. Dans ce cas, vous pouvez probablement passer une minute à éditer la requête SQL;)
http://sqlfiddle.com/#!17/c452d/1