当前位置: 首页 > 面试题库 >

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

严兴旺
2023-03-14
问题内容

我已经在Google的帮助下编写了此查询,以便从表格中创建定界列表,但是我对此查询一无所知。

谁能解释我发生了什么事

 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标签,因此会产生以下错误:

列名“ Data()”包含FOR XML要求的无效XML标识符;’(’(0x0028)是出现错误的第一个字符。

相关的子查询隐藏此错误,仅生成不带标签的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标记,并且在select查询中添加逗号意味着任何带有空格的名称都不会引起错误,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;


 类似资料:
  • 问题内容: 我有3个表,分别为: 应用程序(ID,名称) 资源(ID,名称) ApplicationsResources(id,app_id,resource_id) 我想在GUI上显示所有资源名称的表。我想在每一行的一个单元格中列出该资源的所有应用程序(以逗号分隔)。 所以问题是,在SQL中执行此操作的最佳方法是什么,因为我需要获取所有资源,并且还需要获取每种资源的所有应用程序? 我是否先从资源

  • 问题内容: 我知道如何使用foreach遍历数组的项并附加逗号,但是必须取下最后的逗号总是很痛苦的。有没有简便的PHP方式? 最终我想要 问题答案: 您想为此使用爆破。 即: 有一种附加逗号而不尾随逗号的方法。如果您必须同时进行其他操作,则需要这样做。例如,也许您想引用每个水果,然后将它们全部用逗号分隔: 另外,如果您只是按照“正常”的方式在每个项目后面添加逗号(就像您以前做过的事情一样),并且您

  • 问题内容: 我需要运行类似的查询: 但是我希望子选择返回逗号分隔的列表,而不是数据列。这有可能吗?如果可以,怎么办? 问题答案: 您可以使用GROUP_CONCAT执行该操作,例如

  • 问题内容: 这是我的表结构: 我需要拆分该列,并希望通过一个简单的sql查询来做到这一点,因为我不知道如何使用函数,并且希望将其保持简单。 这是我已经发现的: 但这仅输出 有没有一种方法来拆分一切从到,,等? 提前致谢。 问题答案:

  • 问题内容: 我有看起来像这样的数据: 对于每个customer_id,我需要用逗号分隔的列表,以指示该客户运营的月份: 等等。如何使用SQL Server 2005 SQL(而不是T-SQL)轻松生成此逗号分隔的列表? 我在Stack Overflow和其他地方在这里看到的大多数解决方案似乎都是基于联接多个行值而不是列值来创建逗号分隔的列表: T-SQL FOR XML路径(’‘) 关联的子查询与

  • 问题内容: 我需要这个问题的帮助。 在MYSQL表中,我有一个字段: 我需要找到艺术家uid 401的所有记录 我做这个 我所有记录的artist_list字段值仅是“ 401”,但是如果我有11,401,则此查询不匹配。 任何的想法 ? (我无法使用LIKE方法,因为如果艺术家uid为3(匹配30、33、3333)… 问题答案: 短期解决方案 使用FIND_IN_SET函数: 长期解决方案 标准