[英]What this query does to create comma delimited list SQL Server?
我在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
將刪除第一個逗號和空格。
附錄
要詳細說明知識管理在評論中所說的內容,因為這似乎會獲得更多視圖,轉義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;
從內到外逐步分開。
步驟1:
運行最里面的查詢並查看它產生的內容:
SELECT E2.ename AS 'data()'
FROM emp AS e2
WHERE e2.DEPTNO = 10
FOR XML PATH('')
你應該得到一個類似的輸出:
CLARK KING MILLER
第2步:
該REPLACE
剛剛替換用的空間,
-從而把您的輸出入
CLARK, KING, MILLER
第3步:
外部查詢獲取deptno
值 - 加上內部查詢的結果 - 並生成最終結果。
使用新的STRING_AGG
SQL Server 2017使這一過程變得更加容易。 最近遇到這篇文章並將我的STUFF / FOR XML策略切換為使用新的字符串函數。 還避免了需要額外的JOIN / SUBQUERY和FOR XML的開銷( 以及奇數編碼問題 )並且難以解釋SQL。
SELECT E1.deptno,
STRING_AGG(E1.ename, ', ') AS allemp
FROM EMP AS e1
GROUP BY DEPTNO;
注意 :另外請務必查看對應的STRING_SPLIT
,以便更輕松地使用SQL分隔數據。
外部查詢檢索部門編號列表,然后為每個部門編號運行子查詢以返回屬於該部門的所有名稱。 子查詢使用FOR XML語句將輸出格式化為單行逗號分隔列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.