如何将多行中的文本连接成SQL服务器中的单个文本字符串?

考虑一个包含三行的数据库表:

Peter
Paul
Mary

有没有简单的方法可以把它变成Peter, Paul, Mary的单串?


当我试图用一对多关系连接两个表时,我遇到了类似的问题。 在SQL 2005中,我发现XML PATH方法可以很容易地处理行的连接。

如果有一张名为STUDENTS的表格

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

我预期的结果是:

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

我使用了以下T-SQL

Select Main.SubjectID,
       Left(Main.Students,Len(Main.Students)-1) As "Students"
From
    (
        Select distinct ST2.SubjectID, 
            (
                Select ST1.StudentName + ',' AS [text()]
                From dbo.Students ST1
                Where ST1.SubjectID = ST2.SubjectID
                ORDER BY ST1.SubjectID
                For XML PATH ('')
            ) [Students]
        From dbo.Students ST2
    ) [Main]

如果您可以在一开始时连接逗号并使用substring跳过第一个逗号,则您可以以更紧凑的方式执行相同的操作,因此您不需要执行子查询:

Select distinct ST2.SubjectID, 
    substring(
        (
            Select ','+ST1.StudentName  AS [text()]
            From dbo.Students ST1
            Where ST1.SubjectID = ST2.SubjectID
            ORDER BY ST1.SubjectID
            For XML PATH ('')
        ), 2, 1000) [Students]
From dbo.Students ST2

当存在ORDER BY子句时,此答案可能会返回意外的结果。 为了获得一致的结果,请使用其他答案中详述的FOR XML PATH方法之一。

使用COALESCE

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

只是一些解释(因为这个答案似乎得到相对普遍的看法):

  • Coalesce真的只是一个有用的作弊,它完成了两件事情:
  • 1)不需要用空字符串值初始化@Names

    2)最后不需要剥离额外的分离器。

  • 如果一行有一个NULL Name值,上面的解决方案将得到不正确的结果(如果有一个NULL值,则NULL将在该行之后使@Names NULL,并且下一行将重新以空字符串的形式重新开始。两种解决方案:
  • DECLARE @Names VARCHAR(8000) 
    SELECT @Names = COALESCE(@Names + ', ', '') + Name
    FROM People
    WHERE Name IS NOT NULL
    

    要么:

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

    根据你想要的行为(第一个选项只是过滤NULL,第二个选项通过标记消息将它们保留在列表中[用适合你的任何替代'N / A'])。


    尚未通过MS SQL Server中的XML data()命令显示的一种方法是:

    假设名为NameList的表格带有一个名为FName的列,

    SELECT FName + ', ' AS 'data()' 
    FROM NameList 
    FOR XML PATH('')
    

    收益:

    "Peter, Paul, Mary, "
    

    只有额外的逗号必须处理。

    编辑:正如@ NReilingh的评论中所采用的那样,您可以使用以下方法删除尾部逗号。 假设有相同的表和列名称:

    STUFF(REPLACE((SELECT '#!' + LTRIM(RTRIM(FName)) AS 'data()' FROM NameList
    FOR XML PATH('')),' #!',', '), 1, 2, '') as Brands
    
    链接地址: http://www.djcxy.com/p/24731.html

    上一篇: How to concatenate text from multiple rows into a single text string in SQL server?

    下一篇: Select first row in each GROUP BY group?