我有一个包含以下代码的SQL函数:
DECLARE @CodeNameString varchar(100)
SELECT CodeName FROM AccountCodes ORDER BY Sort
我需要将选择查询的所有结果连接成CodeNameString。
显然,C#代码中的FOREACH循环可以实现此操作,但在SQL中该怎么做呢?
我有一个包含以下代码的SQL函数:
DECLARE @CodeNameString varchar(100)
SELECT CodeName FROM AccountCodes ORDER BY Sort
我需要将选择查询的所有结果连接成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('')
将你的字符串连接成一个长的XML结果(类似于,code1,code2,code3
等),STUFF
在第一个字符处放置一个“空”字符,例如清除“多余”的第一个逗号,以便获得您可能正在寻找的结果。 更新:好的-我理解评论了-如果您数据库表中的文本已经包含像<
、>
或&
这样的字符,则我的当前解决方案实际上会将其编码为<
、>
和&
。如果您对此XML编码有问题-那么是的,您必须查看@KM提出的适用于这些字符的解决方案。我想警告您:这种方法需要更多的资源和处理时间-只是让您知道。<
、&
、>
等),与我之前的答案不同,可以在这里查看:https://dev59.com/Q2445IYBdhLWcg3wH2rH#5031297 - KM.ORDER BY
。 - marc_sDECLARE @CodeNameString varchar(max)
SET @CodeNameString=''
SELECT @CodeNameString=@CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT @CodeNameString
@AlexanderMP的回答是正确的,但你也可以考虑使用coalesce
来处理null值:
declare @CodeNameString nvarchar(max)
set @CodeNameString = null
SELECT @CodeNameString = Coalesce(@CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes
select @CodeNameString
CodeName
而不是@CodeNameString
会更有意义吗?这样可能会丢失数据。最好的方法是使用普通的Where CodeName is not null
,而不是使用coaleste。 - Alex对于SQL Server 2005及以上版本,请使用Coalesce处理null值
,如果是数字类型的值
,则使用Cast或Convert函数 -
declare @CodeNameString nvarchar(max)
select @CodeNameString = COALESCE(@CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort
select @CodeNameString
从MSDN上得知,在SELECT语句中不要使用变量来拼接值(即计算聚合值)。这可能会导致意外的查询结果。原因是SELECT列表中的所有表达式(包括赋值)不能保证对每个输出行都只执行一次。
以上内容似乎表明,如上所述的拼接方式无效,因为赋值可能比选择返回的行数更多。
这里有另一个现实生活中的例子,至少在2008版本(及以后版本)中可以正常工作。
这是原始查询,它使用简单的max()
函数来获取至少一个值:
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
情况问题,并且我们还修复了数字值(字段排序)导致的错误。