将 SQL Server 结果集转换为字符串。

62

我在SQL Server中得到的结果是:

SELECT StudentId FROM Student WHERE condition = xyz

我得到的输出结果如下:

StudentId
1236
7656
8990 ........

存储过程的输出参数是字符串@studentId,我想返回语句为

1236, 7656, 8990.

如何将输出转换成单个字符串?

我正在返回单个列[即学生ID]

11个回答

80

测试这个:

 DECLARE @result NVARCHAR(MAX)

 SELECT @result = STUFF(
                        (   SELECT ',' + CONVERT(NVARCHAR(20), StudentId) 
                            FROM Student 
                            WHERE condition = abc 
                            FOR xml path('')
                        )
                        , 1
                        , 1
                        , '')

1
运行得很好。我成功地将继承的数十个while循环替换为一个字符串来获取电子邮件。 - Nate Anderson

66
DECLARE @result varchar(1000)

SELECT @result = ISNULL(@result, '') + StudentId + ',' FROM Student WHERE condition = xyz

select substring(@result, 0, len(@result) - 1) --trim extra "," at end

2
我刚试了这段代码,它很好用。只需要进行一点调整:使用 select substring(@result, 1, len(@result) -1 ) 去除多余的“,”。 - Eden
3
尝试过这个方法,但在 SQL Server 2008 中最后一行无法��常工作。substring(@result, 1, len(@result) )可以去除尾随的逗号,而上面的版本也会把逗号前面的字符一起去掉。 :) - async
2
应该是 substring(@result, 1, len(@result) - 1)。参考链接:http://msdn.microsoft.com/zh-cn/library/ms187748.aspx - Robino
如果StudentId来自非varchar列,您可能会遇到转换异常。您需要使用CONCAT函数进行正确的连接。请参见下面的答案。 - pistol-pete

12

使用 COALESCE 函数:

DECLARE @StudentID VARCHAR(1000)
SELECT @StudentID = COALESCE(@StudentID + ',', '') + StudentID
FROM Student
WHERE StudentID IS NOT NULL and Condition='XYZ'
select @StudentID

如果StudentId来自非varchar列,您可能会遇到转换异常。您需要使用CONCAT函数进行正确的连接。请参见下面的答案。 - pistol-pete

8

两个答案都是正确的,但不要忘记初始化变量的值,默认值为NULL,并使用T-SQL:

NULL + "Any text" => NULL

这是一个非常普遍的错误,不要忘记它!

此外,使用ISNULL函数是一个好主意:

SELECT @result = @result + ISNULL(StudentId + ',', '') FROM Student

2
“Both answers”这个参考并不是很有用,因为答案会随着时间变化而且不止两个。 - Thronk

6

使用CONCAT函数可避免转换错误:

DECLARE @StudentID VARCHAR(1000)
SELECT @StudentID = CONCAT(COALESCE(@StudentID + ',', ''), StudentID)
FROM Student
WHERE StudentID IS NOT NULL and Condition='XYZ'
select @StudentID

3
以下是MySQL(而不是SQL Server)的解决方案。我在stackoverflow上很难找到MySQL的解决方案,所以我想也许这可以帮助某些人...
参考:https://forums.mysql.com/read.php?10,285268,285286#msg-285286 原始查询... SELECT StudentId FROM Student WHERE condition = xyz 原始结果集...
StudentId
1236
7656
8990

使用concat函数创建新查询...

SELECT group_concat(concat_ws(',', StudentId) separator '; ') 
FROM Student 
WHERE condition = xyz

连接字符串结果集...

StudentId
1236; 7656; 8990

注意:将“separator”更改为您想要的任何内容。
祝好运!

1

brad.v答案是错误的!它不会给你一个连接的字符串。

这是正确的代码,几乎像brad.v的,但有一个重要的改变:

DECLARE @results VarChar(1000)
  SELECT @results = CASE
     WHEN @results IS NULL THEN CONVERT( VarChar(20), [StudentId])
     ELSE @results + ', ' + CONVERT( VarChar(20), [StudentId])
  END
FROM Student WHERE condition = abc;

看到区别了吗? :) brad.v 请修正您的回答,我无法对其进行更正或评论,因为我在这里的声望为零。我想在您修复您的回答后我可以删除我的回答。谢谢!

1
使用STRING_AGG函数:
SELECT STRING_AGG(sub.StudentId, ',') FROM  
(select * from dbo.Students where Name = 'Test3') as sub

如果想使用例如 ORDER BY:

SELECT STRING_AGG(sub.StudentId, ',') WITHIN GROUP(Order by StudentId) FROM  
(select * from dbo.Students where Name = 'Test3') as sub

1

这个方法适用于表中的NULL值,并且不需要在末尾进行子字符串操作。如果表中存在NULL值,COALESCE函数不能很好地处理它们。

DECLARE @results VARCHAR(1000) = '' 
SELECT @results = @results + 
           ISNULL(CASE WHEN LEN(@results) = 0 THEN '' ELSE ',' END + [StudentId], '')
FROM Student WHERE condition = xyz

select @results

0

或者一个单独的选择语句...

DECLARE @results VarChar(1000)
SELECT @results = CASE
     WHEN @results IS NULL THEN CONVERT( VarChar(20), [StudentId])
     ELSE ', ' + CONVERT( VarChar(20), [StudentId])
   END
FROM Student WHERE condition = abc;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接