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?
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 <
, >
, et &
.
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.
DECLARE @CodeNameString varchar(max)
SET @CodeNameString=''
SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT @CodeNameString
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
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
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
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).