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

Peter
Paul
Mary

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


当前回答

此方法仅适用于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]

其他回答

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

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

如果您愿意,我已经创建了程序集,可以在这里下载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函数。

对于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文档提供了如何做到这一点的指南。

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

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

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

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

使用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

要避免空值,可以使用CONCAT()

DECLARE @names VARCHAR(500)
SELECT @names = CONCAT(@names, ' ', name) 
FROM Names
select @names