Je cherche un moyen de concaténer les chaînes d'un champ au sein d'un groupe par requête. Ainsi, par exemple, j'ai une table:
ID COMPANY_ID EMPLOYEE
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave
et je voulais regrouper par company_id pour obtenir quelque chose comme:
COMPANY_ID EMPLOYEE
1 Anna, Bill
2 Carol, Dave
Il y a une fonction intégrée dans mySQL pour faire ceci group_concat
Réponses:
PostgreSQL 9.0 ou version ultérieure:
Les versions récentes de Postgres (depuis fin 2010) ont la
string_agg(expression, delimiter)
fonction qui fera exactement ce que la question demandait, vous permettant même de spécifier la chaîne de délimitation:Postgres 9.0 a également ajouté la possibilité de spécifier une
ORDER BY
clause dans n'importe quelle expression agrégée ; sinon, la commande n'est pas définie. Vous pouvez donc maintenant écrire:Ou bien:
PostgreSQL 8.4 ou version ultérieure:
PostgreSQL 8.4 (en 2009) a introduit la fonction d'agrégation
array_agg(expression)
qui concatène les valeurs dans un tableau. Ensuite,array_to_string()
peut être utilisé pour donner le résultat souhaité:string_agg
pour les versions antérieures à 8.4:Dans le cas où quelqu'un rencontre ce problème à la recherche d'un module de compatibilité pour les bases de données antérieures à la version 9.0, il est possible de tout mettre en œuvre à l'
string_agg
exception de laORDER BY
clause.Ainsi, avec la définition ci-dessous, cela devrait fonctionner de la même manière que dans une base de données Postgres 9.x:
Mais ce sera une erreur de syntaxe:
Testé sur PostgreSQL 8.3.
Variations personnalisées (toutes les versions Postgres)
Avant la version 9.0, 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 cette publication de liste de diffusion , entre autres) consiste à utiliser la
textcat
fonction intégrée (qui se trouve derrière l'||
opérateur):Voici la
CREATE AGGREGATE
documentation.Cela colle simplement toutes les cordes ensemble, sans séparateur. Pour 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:
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:
Si vous préférez supprimer les virgules supplémentaires pour afficher ceci:
Ajoutez ensuite une
ELSIF
vérification à la fonction comme ceci:la source
array_to_string(array_agg(employee), ',')
?Order By
clause à l'intérieur de la fonction d'agrégation, par exemplestring_agg(employee, ',' Order By employee)
Que diriez-vous d'utiliser les fonctions de tableau intégrées de Postgres? Au moins sur 8.4 cela fonctionne hors de la boîte:
la source
Depuis PostgreSQL 9.0, vous pouvez utiliser la fonction d'agrégation appelée string_agg . Votre nouveau SQL devrait ressembler à ceci:
la source
Je ne demande aucun crédit pour la réponse car je l'ai trouvée après quelques recherches:
Ce que je ne savais pas, c'est que PostgreSQL vous permet de définir vos propres fonctions d'agrégation avec CREATE AGGREGATE
Ce message sur la liste PostgreSQL montre à quel point il est trivial de créer une fonction pour faire ce qui est nécessaire:
la source
Comme déjà mentionné, la création de votre propre fonction d'agrégation est la bonne chose à faire. Voici ma fonction d'agrégation de concaténation (vous pouvez trouver des détails en français ):
);
Et puis utilisez-le comme:
la source
Ce dernier extrait de liste d'annonces pourrait être intéressant si vous passez à la version 8.4:
Je créerais un lien vers les documents de développement 8.4, mais ils ne semblent pas encore répertorier cette fonctionnalité.
la source
Suivi de la réponse de Kev, en utilisant les documents Postgres:
Créez d'abord un tableau des éléments, puis utilisez la
array_to_string
fonction intégrée.la source
Suite encore une fois à l'utilisation d'une fonction d'agrégation personnalisée de concaténation de chaînes: vous devez vous rappeler que l'instruction select placera les lignes dans n'importe quel ordre, vous devrez donc effectuer une sous- sélection dans l' instruction from avec une clause order by , et puis une sélection externe avec une clause group by pour agréger les chaînes, ainsi:
la source
J'ai trouvé cette documentation PostgreSQL utile: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html .
Dans mon cas, j'ai cherché du SQL simple pour concaténer un champ avec des crochets autour, si le champ n'est pas vide.
la source
Utilisez la
STRING_AGG
fonction pour PostgreSQL et Google BigQuery SQL :la source
Selon la version PostgreSQL 9.0 et supérieure, vous pouvez utiliser la fonction d'agrégation appelée string_agg. Votre nouveau SQL devrait ressembler à ceci:
la source
Vous pouvez également utiliser la fonction de formatage. Ce qui peut également implicitement prendre en charge la conversion de type de texte, int, etc. par lui-même.
la source
J'utilise Jetbrains Rider et c'était une corvée de copier les résultats des exemples ci-dessus pour les réexécuter, car il semblait tout en JSON. Cela les joint en une seule instruction plus facile à exécuter
la source
Si vous êtes sur Amazon Redshift, où string_agg n'est pas pris en charge, essayez d'utiliser listagg.
la source