Requête SQL - Concaténer les Résultats dans Un String [dupliquer]

cette question a déjà une réponse ici:

  • comment concaténer du texte à partir de plusieurs lignes en une seule chaîne de texte dans SQL server? 44 réponses

j'ai une fonction sql qui inclut ce code:

DECLARE @CodeNameString varchar(100)

SELECT CodeName FROM AccountCodes ORDER BY Sort

je dois concaténer tous les résultats à partir de la requête select dans CodeNameString.

évidemment une boucle FOREACH en code C le ferait, mais comment faire en SQL?

29
demandé sur OMG Ponies 2011-03-04 19:15:05

6 réponses

si vous êtes sur SQL Server 2005 ou plus, vous pouvez utiliser ce FOR XML PATH & STUFF truc:

DECLARE @CodeNameString varchar(100)

SELECT 
   @CodeNameString = STUFF( (SELECT ',' + CodeName 
                             FROM dbo.AccountCodes 
                             ORDER BY Sort
                             FOR XML PATH('')), 
                            1, 1, '')

le FOR XML PATH('') concaténate essentiellement vos chaînes en un seul, résultat XML long (quelque chose comme ,code1,code2,code3 etc.) et le STUFF met un caractère" rien "au premier caractère, par exemple efface la première virgule" superflue", pour vous donner le résultat que vous recherchez probablement.

MISE À JOUR: OK - Je comprends les commentaires - si votre texte dans la table de base de données contient déjà des caractères comme < , > ou & , alors ma solution actuelle codera en fait ceux en &lt; , &gt; , et &amp; .

si vous avez un problème avec cet encodage XML - alors oui, vous devez regarder la solution proposée par @KM qui fonctionne pour ces caractères, aussi. Un mot de avertissement de moi: cette approche est beaucoup plus ressources et traitement intensif-juste pour que vous le sachiez.

74
répondu marc_s 2016-03-30 14:12:02
DECLARE @CodeNameString varchar(max)
SET @CodeNameString=''

SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT @CodeNameString
24
répondu AlexanderMP 2011-03-04 16:18:31

la réponse de @AlexanderMP est correcte, mais vous pouvez également envisager de traiter les nulls avec coalesce :

declare @CodeNameString  nvarchar(max)
set @CodeNameString = null
SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes  
select @CodeNameString
10
répondu James Wiseman 2011-03-04 16:22:26

Pour SQL Server 2005 et au-dessus de l'utilisation Fusionner pour nulls et je suis en utilisant Cast et Convert si il y a des numeric values -

declare @CodeNameString  nvarchar(max)
select  @CodeNameString = COALESCE(@CodeNameString + ',', '')  + Cast(CodeName as varchar) from AccountCodes  ORDER BY Sort
select  @CodeNameString
4
répondu Vishal 2011-03-04 16:29:54

du msdn N'utilisez pas de variable dans une instruction SELECT pour concaténer les valeurs (c'est-à-dire pour calculer les valeurs agrégées). Des résultats inattendus d'interrogation peuvent se produire. C'est parce que toutes les expressions dans la liste de sélection (y compris les assignations) ne sont pas garanties d'être exécutées exactement une fois pour chaque ligne de sortie

le ci-dessus semble dire que la concaténation comme fait ci-dessus n'est pas valide car l'affectation pourrait être faite plus de fois qu'il y a des lignes retournées par le select

2
répondu peter 2014-11-25 16:46:54

Voici un autre exemple réel qui fonctionne bien au moins avec la version 2008 (et plus tard).

c'est la requête originale qui utilise simple max() pour obtenir au moins une des valeurs:

SELECT option_name, Field_M3_name, max(Option_value) AS "Option value", max(Sorting) AS "Sorted"
FROM Value_list group by Option_name, Field_M3_name
ORDER BY option_name, Field_M3_name

version améliorée, où la principale amélioration est que nous montrons toutes les valeurs séparées par des virgules:

SELECT from1.keys, from1.option_name, from1.Field_M3_name,

 Stuff((SELECT DISTINCT ', ' + [Option_value] FROM Value_list from2
  WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Option values",

 Stuff((SELECT DISTINCT ', ' + CAST([Sorting] AS VARCHAR) FROM Value_list from2
  WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'') AS "Sorting"

FROM ((SELECT DISTINCT COALESCE(Option_name,'') + '|' + COALESCE(Field_M3_name,'') AS keys, Option_name, Field_M3_name FROM Value_list)
-- WHERE
) from1
ORDER BY keys

notez que nous avons résolu tous les problèmes possibles NULL cas que je peux penser et aussi nous correction d'une erreur que nous avons obtenue pour les valeurs numériques (Tri des champs).

0
répondu Timo Riikonen 2014-07-11 10:39:45