sql - 此查询如何创建逗号分隔列表 SQL Server?

标签 sql sql-server sql-server-2008

我在谷歌的帮助下编写了这个查询,从表中创建一个分隔列表,但我不明白这个查询中的任何内容。

谁能解释一下发生了什么

 SELECT 
    E1.deptno, 
    allemp = Replace ((SELECT E2.ename AS 'data()' 
                       FROM emp AS e2 
                       WHERE e1.deptno = e2.DEPTNO 
                       FOR xml PATH('')), ' ', ', ') 
 FROM EMP AS e1 
 GROUP BY DEPTNO; 

给我结果

10  CLARK, KING, MILLER
20  SMITH, JONES, SCOTT, ADAMS, FORD
30  ALLEN, WARD, MARTIN, BLAKE, TURNER, JAMES

最佳答案

解释它的最简单方法是查看 FOR XML PATH 对于实际 XML 的工作原理。想象一个简单的表Employee:

EmployeeID      Name
1               John Smith
2               Jane Doe

你可以使用

SELECT  EmployeeID, Name
FROM    emp.Employee
FOR XML PATH ('Employee')

这将创建如下 XML

<Employee>
    <EmployeeID>1</EmployeeID>
    <Name>John Smith</Name>
</Employee>
<Employee>
    <EmployeeID>2</EmployeeID>
    <Name>Jane Doe</Name>
</Employee>

PATH 中删除“Employee”会删除外部 xml 标记,因此此查询:

SELECT  Name
FROM    Employee
FOR XML PATH ('')

会创建

    <Name>John Smith</Name>
    <Name>Jane Doe</Name>

您所做的并不理想,列名“data()”强制出现sql错误,因为它试图创建一个不是合法标签的xml标签,因此会生成以下错误:

Column name 'Data()' contains an invalid XML identifier as required by FOR XML; '('(0x0028) is the first character at fault.

相关子查询隐藏了此错误,只生成不带标签的 XML:

SELECT  Name AS [Data()]
FROM    Employee
FOR XML PATH ('')

创建

John Smith Jane Doe

然后你用逗号替换空格,相当不言自明......

如果我是你,我会稍微调整查询:

SELECT  E1.deptno, 
        STUFF(( SELECT  ', ' + E2.ename 
                FROM    emp AS e2 
                WHERE   e1.deptno = e2.DEPTNO 
                FOR XML PATH('')
            ), 1, 2, '') 
FROM    EMP AS e1 
GROUP BY DEPTNO; 

没有列别名将意味着不会创建 xml 标记,并且在选择查询中添加逗号意味着任何带有空格的名称都不会导致错误,STUFF 将删除第一个逗号和空格。

附录

为了详细说明 KM 在评论中所说的内容,因为这似乎获得了更多的浏览量,转义 XML 字符的正确方法是使用 .value ,如下所示:

SELECT  E1.deptno, 
        STUFF(( SELECT  ', ' + E2.ename 
                FROM    emp AS e2 
                WHERE   e1.deptno = e2.DEPTNO 
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') 
FROM    EMP AS e1 
GROUP BY DEPTNO; 

关于sql - 此查询如何创建逗号分隔列表 SQL Server?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10381512/

相关文章:

sql - TSQL 批量插入

java - 比较从数据库获取的java中的两个值

SQL 查询 : joining 3 tables with multiple values

MySQL Multicase When Exists 语句

sql - 如何在 Postgresql 中传播/分布数字

MySQL 永无止境 'Copying to tmp table' 与 db View 和 LEFT JOIN

sql-server - 非数字索引的表现

sql-server - 将所有数据库从源加载到 ADLG2(azure data Lake gen2)

sql-server-2008 - 将数百万行从一个 SQL Server 数据库复制到另一个数据库的最佳方法是什么?

sql - SQL Server 2008存储过程中如何操作ntext类型的数据