SQL查询 – 将结果连接成一个string
我有一个包含这个代码的sql函数:
DECLARE @CodeNameString varchar(100) SELECT CodeName FROM AccountCodes ORDER BY Sort
我需要将select查询的所有结果连接到CodeNameString。
很明显,C#代码中的FOREACH循环会执行此操作,但是如何在SQL中执行此操作?
如果您使用的是SQL Server 2005或更高版本,则可以使用以下FOR XML PATH & STUFF
技巧:
DECLARE @CodeNameString varchar(100) SELECT @CodeNameString = STUFF( (SELECT ',' + CodeName FROM dbo.AccountCodes ORDER BY Sort FOR XML PATH('')), 1, 1, '')
FOR XML PATH('')
基本上将你的string连接成一个长的XML结果(类似于,code1,code2,code3
等),并且STUFF
在第一个字符处放置一个“nothing”字符,例如,code1,code2,code3
“多余的“第一个逗号,给你你可能正在寻找的结果。
更新:好的 – 我理解评论 – 如果你的数据库表中的文本已经包含字符,如<
, >
或&
,那么我当前的解决scheme实际上将它们编码到<
, >
和&
。
如果你的XML编码有问题 – 那么是的,你必须看看由@KM提出的解决scheme,也适用于这些字符。 我的一个警告 :这种方法是更多的资源和处理密集型 – 只是你知道。
DECLARE @CodeNameString varchar(max) SET @CodeNameString='' SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort SELECT @CodeNameString
@AlexanderMP的回答是正确的,但你也可以考虑处理与coalesce
空值:
declare @CodeNameString nvarchar(max) set @CodeNameString = null SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes select @CodeNameString
对于SQL Server 2005及以上版本,使用Coalesce for nulls
,如果有numeric values
则使用Cast或Convert –
declare @CodeNameString nvarchar(max) select @CodeNameString = COALESCE(@CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort select @CodeNameString
从msdn不要在SELECT语句中使用variables来连接值(即计算聚合值)。 意外的查询结果可能会发生。 这是因为SELECT列表中的所有expression式(包括赋值)不能保证每个输出行只执行一次
上面似乎说,如上所述的连接是无效的,因为分配可能被执行多次,而不是由select所返回的行
这是另一个现实生活中的例子,至less在2008年发布(以及后来)的工作正常。
这是使用简单的max()
获取至less一个值的原始查询:
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
改进版本,其中主要改进之处在于我们显示的所有值都以逗号分隔:
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
请注意,我们已经解决了所有可能的NULL
情况下我能想到的问题,也解决了我们的数值(字段sorting)的错误。