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

Peter
Paul
Mary

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


当前回答

在SQL Server 2017或更高版本中,可以使用STRING_AGG()函数生成逗号分隔的值。请看下面的一个示例。

SELECT
    VendorId, STRING_AGG(FirstName,',') UsersName
FROM Users
WHERE VendorId != 9
GROUP BY VendorId

其他回答

此答案需要服务器上的某些权限才能工作。

装配是一个很好的选择。有很多网站解释如何创建它。我认为解释得很好的就是这个。

如果您愿意,我已经创建了程序集,可以在这里下载DLL文件。

下载后,需要在SQL Server中运行以下脚本:

EXEC sp_configure 'show advanced options', 1
RECONFIGURE;
EXEC sp_configure 'clr strict security', 1;
RECONFIGURE;

CREATE Assembly concat_assembly
   AUTHORIZATION dbo
   FROM '<PATH TO Concat.dll IN SERVER>'
   WITH PERMISSION_SET = SAFE;
GO

CREATE AGGREGATE dbo.concat (

    @Value NVARCHAR(MAX)
  , @Delimiter NVARCHAR(4000)

) RETURNS NVARCHAR(MAX)
EXTERNAL Name concat_assembly.[Concat.Concat];
GO

sp_configure 'clr enabled', 1;
RECONFIGURE

请注意,服务器可以访问程序集的路径。由于您已成功完成所有步骤,因此可以使用以下功能:

SELECT dbo.Concat(field1, ',')
FROM Table1

自SQL Server 2017以来,可以使用STRING_AGG函数。

使用COALESCE-从这里了解更多信息

例如:

102103104

然后在SQL Server中编写以下代码,

Declare @Numbers AS Nvarchar(MAX) -- It must not be MAX if you have few numbers
SELECT  @Numbers = COALESCE(@Numbers + ',', '') + Number
FROM   TableName where Number IS NOT NULL

SELECT @Numbers

输出将是:

102,103,104

我并没有做过任何关于性能的分析,因为我的列表中只有不到10项,但在查看了30多个答案后,我感到很惊讶,我仍然对已经给出的类似答案进行了修改,类似于对单个组列表使用COALESCE,甚至不必设置我的变量(无论如何默认为NULL),并且它假设我的源数据表中的所有条目都是非空的:

DECLARE @MyList VARCHAR(1000), @Delimiter CHAR(2) = ', '
SELECT @MyList = CASE WHEN @MyList > '' THEN @MyList + @Delimiter ELSE '' END + FieldToConcatenate FROM MyData

我确信COALENCE内部使用了相同的想法。让我们希望微软不会在我身上改变这一点。

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

使用此项:

ISNULL(SUBSTRING(REPLACE((select ',' FName as 'data()' from NameList for xml path('')), ' ,',', '), 2, 300), '') 'MyList'

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