PostgreSQL 9.0 ou plus récent :
Les Postgres modernes (depuis 2010) disposent de la fonction string_agg(expression, delimiter)
qui fera exactement ce que l'auteur de la demande recherchait :
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 a également ajouté la possibilité de spécifier un fichier de type ORDER BY
clause dans toute expression agrégée sinon vous devez ordonner tous vos résultats ou faire face à un ordre indéfini. Vous pouvez donc maintenant écrire :
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x :
Introduction de PostgreSQL 8.4 (en 2009) la fonction agrégée array_agg(expression)
qui rassemble les valeurs dans un tableau. Ensuite, array_to_string()
peut être utilisé pour obtenir le résultat souhaité :
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x et plus ancien :
Lorsque cette question a été posée à l'origine, il n'existait pas de fonction d'agrégation intégrée permettant de concaténer des chaînes de caractères. L'implémentation personnalisée la plus simple ( suggéré par Vajda Gabo dans ce message de liste de diffusion parmi beaucoup d'autres) est d'utiliser la fonction intégrée textcat
(qui se trouve derrière la fonction ||
opérateur) :
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Voici le CREATE AGGREGATE
documentation.
Cela colle simplement toutes les cordes ensemble, sans séparateur. Afin d'obtenir un ", " inséré entre elles sans l'avoir à la fin, vous pouvez créer votre propre fonction de concaténation et la substituer à la fonction "textcat" ci-dessus. En voici une que j'ai créée et testée sous 8.3.12 :
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
Cette version affichera une virgule même si la valeur de la ligne est nulle ou vide, de sorte que vous obtenez un résultat comme celui-ci :
a, b, c, , e, , g
Si vous préférez supprimer les virgules supplémentaires pour l'affichage :
a, b, c, e, g
Ajoutez ensuite un ELSIF
à la fonction comme ceci :
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
1 votes
La réponse de Markus Döring est techniquement meilleure.
0 votes
@pstanton, la réponse de Döring n'est meilleure que pour les versions 8.4 et inférieures.
0 votes
Cette question semble mieux convenir à dba.stackexchange.com .
0 votes
Ceci devrait être la réponse valide maintenant stackoverflow.com/a/47638417/243233