PostgreSQL 9.0 ou version ultérieure :
Postgres moderne (depuis 2010) a le string_agg(expression, delimiter)
fonction qui fera exactement ce que le demandeur recherchait :
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 a également ajouté la possibilité de spécifier un ORDER BY
clause dans toute expression agrégée ; sinon vous devez ordonner tous vos résultats ou traiter 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 :
PostgreSQL 8.4 (en 2009) a introduit la fonction d'agrégation array_agg(expression)
qui collecte les valeurs dans un tableau. Puis array_to_string()
peut être utilisé pour donner le résultat souhaité :
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x et versions antérieures :
Lorsque cette question a été posée à l'origine, il n'y avait pas de fonction d'agrégation intégrée pour concaténer les chaînes. L'implémentation personnalisée la plus simple (suggérée par Vajda Gabo dans cet article de liste de diffusion, parmi tant d'autres) consiste à utiliser le textcat
intégré fonction (qui se trouve derrière le ||
opérateur):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Voici le CREATE AGGREGATE
documents.
Cela colle simplement toutes les cordes ensemble, sans séparateur. Afin d'obtenir un ", " inséré entre eux sans l'avoir à la fin, vous pouvez créer votre propre fonction de concaténation et la remplacer par le "textcat" ci-dessus. En voici un que j'ai assemblé et testé le 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, vous obtenez donc une sortie comme celle-ci :
a, b, c, , e, , g
Si vous préférez supprimer les virgules supplémentaires pour afficher ceci :
a, b, c, e, g
Ajoutez ensuite un ELSIF
vérifiez 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;