Considérons une table de base de données contenant des noms, avec trois lignes:
Peter
Paul
Mary
Existe-t-il un moyen facile de transformer cela en une seule chaîne de Peter, Paul, Mary
?
Considérons une table de base de données contenant des noms, avec trois lignes:
Peter
Paul
Mary
Existe-t-il un moyen facile de transformer cela en une seule chaîne de Peter, Paul, Mary
?
Réponses:
Si vous êtes sur SQL Server 2017 ou Azure, consultez la réponse de Mathieu Renda .
J'ai rencontré un problème similaire lorsque j'essayais de joindre deux tables avec des relations un à plusieurs. Dans SQL 2005, j'ai trouvé que cette
XML PATH
méthode peut gérer la concaténation des lignes très facilement.S'il y a une table appelée
STUDENTS
Le résultat que j'attendais était:
J'ai utilisé ce qui suit
T-SQL
:Vous pouvez faire la même chose de manière plus compacte si vous pouvez concaténer les virgules au début et utiliser
substring
pour ignorer la première afin que vous n'ayez pas besoin de faire une sous-requête:la source
<
ou&
. Voir le commentaire de @ BenHinman.FOR XML PATH ('')
. Cela signifie qu'il ne doit pas être considéré comme fiable, car tout correctif ou mise à jour pourrait altérer son fonctionnement. Cela repose essentiellement sur une fonctionnalité obsolète.FOR XML
est de générer du XML, pas de concaténer des chaînes arbitraires. Voilà pourquoi il échappe&
,<
et>
aux codes d'entité XML (&
,<
,>
). Je suppose que ce sera aussi échapper"
et'
à"
et'
dans les attributs aussi bien. Il est pasGROUP_CONCAT()
,string_agg()
,array_agg()
,listagg()
, etc. , même si vous pouvez faire ce genre de le faire. Nous devrions passer notre temps à demander à Microsoft de mettre en place une fonction appropriée.string_agg
dans v.Next. et tout cela peut disparaître.Utilisation
COALESCE
:Juste quelques explications (puisque cette réponse semble obtenir des vues relativement régulières):
1) Pas besoin d'initialiser
@Names
avec une valeur de chaîne vide.2) Pas besoin de retirer un séparateur supplémentaire à la fin.
@Names
NULL après cette ligne, et la ligne suivante recommencera comme une chaîne vide. Facilement corrigé avec l'un des deux solutions:ou:
Selon le comportement que vous souhaitez (la première option filtre uniquement les valeurs NULL , la seconde les conserve dans la liste avec un message marqueur [remplacez «N / A» par ce qui vous convient]).
la source
SQL Server 2017+ et SQL Azure: STRING_AGG
À partir de la prochaine version de SQL Server, nous pouvons enfin concaténer sur plusieurs lignes sans avoir à recourir à une variable ou à une sorcellerie XML.
STRING_AGG (Transact-SQL)
Sans regroupement
Avec regroupement:
Avec regroupement et sous-tri
la source
Une méthode non encore montrée via la
XML
data()
commande dans MS SQL Server est:Supposons une table appelée NameList avec une colonne appelée FName,
Retour:
Seule la virgule supplémentaire doit être traitée.
Modifier: Comme adopté à partir du commentaire de @ NReilingh, vous pouvez utiliser la méthode suivante pour supprimer la virgule de fin. En supposant les mêmes noms de table et de colonne:
la source
+ ', '
il ajoute toujours un espace unique entre chaque élément concaténé.SELECT STUFF(REPLACE((SELECT '#!'+city AS 'data()' FROM #cityzip FOR XML PATH ('')),' #!',', '),1,2,'')
Dans SQL Server 2005
Dans SQL Server 2016
vous pouvez utiliser la syntaxe FOR JSON
c'est à dire
Et le résultat deviendra
Cela fonctionnera même si vos données contiennent des caractères XML non valides
le
'"},{"_":"'
est sûr parce que si vos données contiennent,'"},{"_":"',
il sera échappé à"},{\"_\":\"
Vous pouvez remplacer
', '
par n'importe quel séparateur de chaînesEt dans SQL Server 2017, Azure SQL Database
Vous pouvez utiliser la nouvelle fonction STRING_AGG
la source
<
,>
,&
, etc. , quiFOR XML PATH('')
échapperont automatiquement.Dans MySQL, il existe une fonction, GROUP_CONCAT () , qui vous permet de concaténer les valeurs de plusieurs lignes. Exemple:
la source
SEPARATOR '", "'
je manquerai quelques caractères à la fin de la dernière entrée. pourquoi cela peut-il arriver?CHAR
, vous devez le caster, par exemple viaGROUP_CONCAT( CAST(id AS CHAR(8)) ORDER BY id ASC SEPARATOR ',')
2) si vous avez de nombreuses valeurs à venir, vous devez augmenter legroup_concat_max_len
comme écrit dans stackoverflow.com/a/1278210/1498405Utilisez COALESCE - En savoir plus d'ici
À titre d'exemple:
Ensuite, écrivez le code ci-dessous dans le serveur SQL,
La sortie serait:
la source
Declare @Numbers AS Nvarchar(MAX)
et cela a bien fonctionné. Pouvez-vous expliquer pourquoi vous recommandez de ne pas l'utiliser s'il vous plaît?Les tableaux Postgres sont géniaux. Exemple:
Créez des données de test:
Les agréger dans un tableau:
Convertissez le tableau en une chaîne séparée par des virgules:
TERMINÉ
Depuis PostgreSQL 9.0, c'est encore plus simple .
la source
select array_to_string(array_agg(name||'('||id||')'
Oracle 11g Release 2 prend en charge la fonction LISTAGG. Documentation ici .
Attention
Soyez prudent lors de l'implémentation de cette fonction s'il est possible que la chaîne résultante dépasse 4 000 caractères. Cela lèvera une exception. Si tel est le cas, vous devez gérer l'exception ou lancer votre propre fonction qui empêche la chaîne jointe de dépasser 4 000 caractères.
la source
LISTAGG
fonctionne parfaitement! Lisez simplement le document lié ici.wm_concat
supprimé à partir de la version 12c.Dans SQL Server 2005 et versions ultérieures, utilisez la requête ci-dessous pour concaténer les lignes.
la source
<
ou&
.Je n'ai pas accès à un serveur SQL à la maison, donc je suppose que la syntaxe ici, mais c'est plus ou moins:
la source
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ' ' END + Name FROM Names
SELECT @names = @names + ISNULL(' ' + Name, '')
Une solution CTE récursive a été suggérée, mais aucun code n'a été fourni. Le code ci-dessous est un exemple de CTE récursif. Notez que bien que les résultats correspondent à la question, les données ne correspondent pas tout à fait à la description donnée, car je suppose que vous voulez vraiment faire cela sur des groupes de lignes, pas toutes les lignes du tableau. Le modifier pour qu'il corresponde à toutes les lignes du tableau reste un exercice pour le lecteur.
la source
name
colonne en une chaîne séparée par des virgules pour 4 groupes deid
s. À première vue, je pense que c'est plus de travail que ce que font la plupart des autres solutions pour SQL Server.À partir de PostgreSQL 9.0, c'est assez simple:
Dans les versions antérieures à 9.0
array_agg()
peuvent être utilisées comme indiqué par hgmnzla source
SELECT string_agg(non_text_type::text, ',') FROM table
varchar
ouchar
Vous devez créer une variable qui contiendra votre résultat final et le sélectionner, comme ça.
Solution la plus simple
la source
Dans SQL Server vNext, cela sera intégré à la fonction STRING_AGG, en savoir plus à ce sujet ici: https://msdn.microsoft.com/en-us/library/mt790580.aspx
la source
L'utilisation de XML m'a aidé à séparer les lignes par des virgules. Pour la virgule supplémentaire, nous pouvons utiliser la fonction de remplacement de SQL Server. Au lieu d'ajouter une virgule, l'utilisation de l'AS 'data ()' concaténera les lignes avec des espaces, qui pourront ensuite être remplacés par des virgules comme syntaxe écrite ci-dessous.
la source
Une solution prête à l'emploi, sans virgule supplémentaire:
Une liste vide entraînera une valeur NULL. Habituellement, vous insérerez la liste dans une colonne de tableau ou une variable de programme: ajustez la longueur maximale de 255 selon vos besoins.
(Diwakar et Jens Frandsen ont fourni de bonnes réponses, mais doivent être améliorées.)
la source
', '
par','
si vous ne voulez pas d'espace supplémentaire.Voici un exemple:
la source
Cela place la virgule errante au début.
Cependant, si vous avez besoin d'autres colonnes, ou pour CSV une table enfant, vous devez l'encapsuler dans un champ défini par l'utilisateur scalaire (UDF).
Vous pouvez également utiliser le chemin XML comme sous-requête corrélée dans la clause SELECT (mais je devrais attendre de retourner au travail parce que Google ne fait pas de travail à la maison :-)
la source
Avec les autres réponses, la personne qui lit la réponse doit connaître une table de domaine spécifique telle que véhicule ou étudiant. La table doit être créée et remplie de données pour tester une solution.
Voici un exemple qui utilise la table SQL Server "Information_Schema.Columns". En utilisant cette solution, aucune table ne doit être créée ni aucune donnée ajoutée. Cet exemple crée une liste de noms de colonnes séparés par des virgules pour toutes les tables de la base de données.
la source
Pour les bases de données Oracle, consultez cette question: comment concaténer plusieurs lignes en une seule dans Oracle sans créer de procédure stockée?
La meilleure réponse semble être de @Emmanuel, en utilisant la fonction intégrée LISTAGG (), disponible dans Oracle 11g version 2 et versions ultérieures.
comme l'a souligné @ user762952, et selon la documentation d'Oracle http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php , la fonction WM_CONCAT () est également une option. Il semble stable, mais Oracle recommande explicitement de ne pas l'utiliser pour toute application SQL, donc utilisez-le à vos risques et périls.
En dehors de cela, vous devrez écrire votre propre fonction; le document Oracle ci-dessus contient un guide sur la façon de procéder.
la source
Pour éviter les valeurs nulles, vous pouvez utiliser CONCAT ()
la source
J'ai vraiment aimé l'élégance de la réponse de Dana . Je voulais juste le terminer.
la source
SELECT @names = @names + CASE WHEN LEN(@names)=0 THEN '' ELSE ', ' END + Name FROM Names
alors vous n'aurez pas à la tronquer par la suite.Cette réponse nécessitera certains privilèges sur le serveur pour fonctionner.
Les assemblages sont une bonne option pour vous. Il existe de nombreux sites qui expliquent comment le créer. Celui que je pense est très bien expliqué est celui- ci
Si vous le souhaitez, j'ai déjà créé l'assemblage, et il est possible de télécharger la DLL ici .
Une fois que vous l'avez téléchargé, vous devrez exécuter le script suivant dans votre serveur SQL:
Notez que le chemin d'accès à l'assembly peut être accessible au serveur. Puisque vous avez réussi toutes les étapes, vous pouvez utiliser la fonction comme:
J'espère que cela aide!!!
la source
Exemple complet MySQL:
Nous avons des utilisateurs qui peuvent avoir de nombreuses données et nous voulons avoir une sortie, où nous pouvons voir toutes les données des utilisateurs dans une liste:
Résultat:
Configuration de la table:
Requete:
la source
J'utilise généralement select comme ceci pour concaténer des chaînes dans SQL Server:
la source
Si vous souhaitez traiter les valeurs nulles, vous pouvez le faire en ajoutant une clause where ou en ajoutant une autre COALESCE autour de la première.
la source
Cela a fonctionné pour moi ( SqlServer 2016 ):
Voici la source: https://www.mytecbits.com/
Et une solution pour MySql (puisque cette page apparaît dans Google pour MySql)
De MySql Documentations
la source
Dans Oracle, c'est le cas
wm_concat
. Je crois que cette fonction est disponible dans la version 10g et supérieure.la source
Cela peut aussi être utile
Retour
la source