考虑一个包含名称的数据库表,其中有三行:

Peter
Paul
Mary

有没有一种简单的方法可以把它变成彼得、保罗、玛丽的一串?


当前回答

我在家里无法访问SQL Server,所以我猜测这里的语法,但大致上是这样的:

DECLARE @names VARCHAR(500)

SELECT @names = @names + ' ' + Name
FROM Names

其他回答

SELECT STUFF((SELECT ', ' + name FROM [table] FOR XML PATH('')), 1, 2, '')

下面是一个示例:

DECLARE @t TABLE (name VARCHAR(10))
INSERT INTO @t VALUES ('Peter'), ('Paul'), ('Mary')
SELECT STUFF((SELECT ', ' + name FROM @t FOR XML PATH('')), 1, 2, '')
--Peter, Paul, Mary

在SQL Server 2005中

SELECT Stuff(
  (SELECT N', ' + Name FROM Names FOR XML PATH(''),TYPE)
  .value('text()[1]','nvarchar(max)'),1,2,N'')

在SQL Server 2016中

可以使用FOR JSON语法

SELECT per.ID,
Emails = JSON_VALUE(
   REPLACE(
     (SELECT _ = em.Email FROM Email em WHERE em.Person = per.ID FOR JSON PATH)
    ,'"},{"_":"',', '),'$[0]._'
) 
FROM Person per

结果会变成

Id  Emails
1   abc@gmail.com
2   NULL
3   def@gmail.com, xyz@gmail.com

即使您的数据包含无效的XML字符,这也会起作用

“”},{“_”:“”是安全的,因为如果您的数据包含“”},{”_“:“”,它将被转义为“},{\”_\“:\”

可以用任何字符串分隔符替换“,”


在SQL Server 2017中,Azure SQL数据库

您可以使用新的STRING_AGG函数

使用“TABLE”类型非常容易。让我们假设您的表名为Students,并且它具有列名。

declare @rowsCount INT
declare @i INT = 1
declare @names varchar(max) = ''

DECLARE @MyTable TABLE
(
  Id int identity,
  Name varchar(500)
)
insert into @MyTable select name from Students
set @rowsCount = (select COUNT(Id) from @MyTable)

while @i < @rowsCount
begin
 set @names = @names + ', ' + (select name from @MyTable where Id = @i)
 set @i = @i + 1
end
select @names

此示例使用SQL Server 2008 R2进行了测试。

在SQL Server vNext中,这将内置STRING_AGG函数。在STRING_AGG(Transact-SQL)中了解有关它的更多信息。

此方法仅适用于Teradata Aster数据库,因为它使用NPATH函数。

再次,我们有桌上学生

SubjectID       StudentName
----------      -------------
1               Mary
1               John
1               Sam
2               Alaina
2               Edward

然后使用NPATH,只需一次SELECT:

SELECT * FROM npath(
  ON Students
  PARTITION BY SubjectID
  ORDER BY StudentName
  MODE(nonoverlapping)
  PATTERN('A*')
  SYMBOLS(
    'true' as A
  )
  RESULT(
    FIRST(SubjectID of A) as SubjectID,
    ACCUMULATE(StudentName of A) as StudentName
  )
);

结果:

SubjectID       StudentName
----------      -------------
1               [John, Mary, Sam]
2               [Alaina, Edward]