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

Peter
Paul
Mary

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


当前回答

这对我有用(SQL Server 2016):

SELECT CarNamesString = STUFF((
         SELECT ',' + [Name]
            FROM tbl_cars
            FOR XML PATH('')
         ), 1, 1, '')

来源如下:https://www.mytecbits.com/

还有一个针对MySQL的解决方案(因为该页面显示在Google for MySQL中):

SELECT [Name],
       GROUP_CONCAT(DISTINCT [Name]  SEPARATOR ',')
       FROM tbl_cars

来自MySQL文档。

其他回答

我真的很喜欢Dana回答的优雅,只想让它变得完整。

DECLARE @names VARCHAR(MAX)
SET @names = ''

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

-- Deleting last two symbols (', ')
SET @sSql = LEFT(@sSql, LEN(@sSql) - 1)

首先,您应该声明一个表变量并用表数据填充它,然后,使用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

对于Oracle DB,请参阅以下问题:如何在Oracle中将多行连接成一行而不创建存储过程?

最好的答案似乎是@Emmanuel,使用了内置的LISTAGG()函数,该函数在Oracle 11g Release 2和更高版本中提供。

SELECT question_id,
   LISTAGG(element_id, ',') WITHIN GROUP (ORDER BY element_id)
FROM YOUR_TABLE;
GROUP BY question_id

正如@user762952所指出的,根据Oracle的文档http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php,WM_CONCAT()函数也是一个选项。它看起来很稳定,但Oracle明确建议不要将它用于任何应用程序SQL,因此使用时风险自负。

除此之外,您还必须编写自己的函数;上面的Oracle文档提供了如何做到这一点的指南。

如果要处理null,可以通过添加where子句或在第一个子句周围添加另一个COALENCE来完成。

DECLARE @Names VARCHAR(8000) 
SELECT @Names = COALESCE(COALESCE(@Names + ', ', '') + Name, @Names) FROM People

在SQL Server中实现这一点的一种方法是将表内容返回为XML(对于XML原始),将结果转换为字符串,然后用“,”替换标记。