如何在SQL Server中将多行文本连接成单个文本字符串

2398

考虑一个包含姓名的数据库表格,有三行:

Peter
Paul
Mary

有没有简单的方法将这些内容转换成一个字符串:Peter, Paul, Mary

29
如需针对SQL Server的特定答案,请尝试此问题 - Matt Hamilton
22
对于MySQL,请查看此答案中的Group_Concat。它可以将多行合并为一个字段。 - Pykler
31
希望SQL Server的下一个版本能够添加一项新功能,以优雅地解决多行字符串连接的问题,而不需要使用 FOR XML PATH 这种繁琐方式。 - Pete Alvin
4
不是SQL,但如果这只是一次性的事情,你可以将列表粘贴到这个在线工具convert.town/column-to-comma-separated-list中进行转换。 - Stack Man
4
在Oracle数据库中,你可以在11g r2版本之后使用LISTAGG(COLUMN_NAME)函数,它可以实现与旧版中不被支持的WM_CONCAT(COLUMN_NAME)函数相同的功能。 - Richard
显示剩余5条评论
48个回答

1
SELECT PageContent = Stuff(
    (   SELECT PageContent
        FROM dbo.InfoGuide
        WHERE CategoryId = @CategoryId
          AND SubCategoryId = @SubCategoryId
        for xml path(''), type
    ).value('.[1]','nvarchar(max)'),
    1, 1, '')
FROM dbo.InfoGuide info

需要解释一下。请通过编辑(更改)您的答案进行回复,而不是在评论中回复(不要包含“Edit:”、“Update:”或类似内容——答案应该看起来像是今天写的)。 - Peter Mortensen

1
使用这个:
ISNULL(SUBSTRING(REPLACE((select ',' FName as 'data()' from NameList for xml path('')), ' ,',', '), 2, 300), '') 'MyList'

其中的“300”可以是任何宽度,考虑到您认为会显示的最大项目数量。


1
如果你发现自己不得不提前猜测结果中会有多少行,那么你做错了。 - Geoff Griswald

1
在Oracle中有几种方法:
    create table name
    (first_name varchar2(30));

    insert into name values ('Peter');
    insert into name values ('Paul');
    insert into name values ('Mary');

解决方案1:

    select substr(max(sys_connect_by_path (first_name, ',')),2) from (select rownum r, first_name from name ) n start with r=1 connect by prior r+1=r
    o/p=> Peter,Paul,Mary

解决方案是2:
    select  rtrim(xmlagg (xmlelement (e, first_name || ',')).extract ('//text()'), ',') first_name from name
    o/p=> Peter,Paul,Mary

1
使用“TABLE”类型非常容易。假设您的表名为“Students”,并且它有一个名为“name”的列。
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 版本下测试的。


0
我们可以使用递归、CTE和union ALL来实现。
declare @mytable as table(id int identity(1,1), str nvarchar(100))
insert into @mytable values('Peter'),('Paul'),('Mary')

declare @myresult as table(id int,str nvarchar(max),ind int, R# int)

;with cte as(select id,cast(str as nvarchar(100)) as str, cast(0 as int) ind from @mytable
union all
select t2.id,cast(t1.str+',' +t2.str as nvarchar(100)) ,t1.ind+1 from cte t1 inner join @mytable t2 on t2.id=t1.id+1)
insert into @myresult select *,row_number() over(order by ind) R# from cte

select top 1 str from @myresult order by R# desc

0
首先,您应该声明一个表变量并将其填充为您的表数据,然后使用 WHILE 循环逐行选择并将其值添加到 nvarchar(max) 变量中。
    Go
    declare @temp table(
        title nvarchar(50)
    )
    insert into @temp(title)
    select p.Title from dbo.person p
    --
    declare @mainString nvarchar(max)
    set @mainString = '';
    --
    while ((select count(*) from @temp) != 0)
    begin
        declare @itemTitle nvarchar(50)
        set @itemTitle = (select top(1) t.Title from @temp t)
    
        if @mainString = ''
        begin
            set @mainString = @itemTitle
        end
        else
        begin
            set @mainString = concat(@mainString,',',@itemTitle)
        end
    
        delete top(1) from @temp
    
    end
    print @mainString

1
看起来是一个很好的答案,但请解释一下这段代码是如何工作的。 - MeanGreen
1
这似乎会有非常低效的边界——如何在一百万行上工作? - user2864740
while循环?这不是非SQL的吗? - Peter Mortensen

0
在SQL Server 2017或更高版本中,您可以使用STRING_AGG函数将多行文本连接成一个单一的文本字符串。以下是一个示例,展示了如何实现这一点:
假设您有一个名为"Names"的表,其中有一个名为"Name"的列,分别包含Peter、Paul和Mary的值,您可以使用以下SQL查询:
SELECT STRING_AGG(Name, ', ') AS ConcatenatedNames
FROM Names;

这个查询将返回一个由名字连接并用逗号分隔的字符串。
ConcatenatedNames
-----------------
Peter, Paul, Mary

-5
   declare @phone varchar(max)='' 
   select @phone=@phone + mobileno +',' from  members
   select @phone

为什么不用 +,因为 OP 想要这样做,并且你不会删除最后一个 ;。我认为 这个答案 是相同的,还有 这个答案 ;)。 - shA.t
我遇到了这个问题,找到了答案,但我想用“;”连接起来,因此我在这里粘贴,最后一个元素为空。 - Hamid Bahmanabady
4
当您在此处发布答案时,应与问题相关,并且您的代码结果应为Null,因为您从@phone IS Null开始并添加到Null在SQL Server中将会是Null。我认为您忘记添加类似于在第一行后添加= ''之类的内容;)。 - shA.t
不,我会在检查后发布答案,只有当结果不为空时。 - Hamid Bahmanabady

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