2016-07-06 78 views
2

我正在使用Microsoft SQL Server。具有多個子元素的SQL查詢分層XML

我有一個簡單的層次結構像在XML中的定向圖表:

DECLARE @XML as XML = CAST(
'<ROOT> 
    <NODE NODE_ID="1"> 
     <EDGE>2</EDGE> 
     <EDGE>3</EDGE> 
     <EDGE>4</EDGE> 
    </NODE> 
    <NODE NODE_ID="2"> 
     <EDGE>1</EDGE> 
     <EDGE>3</EDGE> 
    </NODE> 
</ROOT>' AS XML); 

我所需的輸出會是這樣的表:

SOURCE_NODE_ID | DEST_NODE_ID 
1    | 2 
1    | 3 
1    | 4 
2    | 1 
2    | 3 

的查詢是這樣的:

SELECT B.value('data(@NODE_ID)','int') AS SOURCE_NODE_ID, 
     A.B.value('(EDGE/text())[1]', 'int') AS DEST_NODE_ID 
FROM @XML.nodes('/ROOT/NODE') AS A(B); 

只返回第一邊緣:

SOURCE_NODE_ID | DEST_NODE_ID 
1    | 2 
2    | 1 

這人做一個好一點:

SELECT B.value('data(@NODE_ID)','int') AS SOURCE_NODE_ID, 
     B.query('EDGE').value('.', 'int') AS DEST_NODE_ID 
FROM @XML.nodes('/ROOT/NODE') AS A(B); 

只有它加到所有邊緣到一個單元格:

SOURCE_NODE_ID | DEST_NODE_ID 
1    | 234 
2    | 13 

我怎樣才能得到我想要的結果?我應該加入一個內部查詢或什麼?可能我讓它太複雜了,當然有一個簡單的解決方案呢?

+0

這是一個很好的問題:Copy'n'pasteable測試代碼,自己的努力,預計輸出,清晰的解釋..如果只有所有的問題都是這樣的:-)投了票! – Shnugo

回答

4

嘗試像這樣

由於有很多NODE元素,你需要調用.nodes()他們。由於嵌套了許多EDGE元素,因此您需要爲它們調用CROSS APPLY .nodes()

其餘的是容易...

DECLARE @XML as XML = CAST(
'<ROOT> 
    <NODE NODE_ID="1"> 
     <EDGE>2</EDGE> 
     <EDGE>3</EDGE> 
     <EDGE>4</EDGE> 
    </NODE> 
    <NODE NODE_ID="2"> 
     <EDGE>1</EDGE> 
     <EDGE>3</EDGE> 
    </NODE> 
</ROOT>' AS XML); 

SELECT Nd.value('@NODE_ID','INT') AS SOURCE_NODE_ID 
     ,Edg.value('.','INT') AS DEST_NODE_ID 
FROM @XML.nodes('/ROOT/NODE') AS A(Nd) 
CROSS APPLY A.Nd.nodes('EDGE') AS B(Edg) 

結果

SOURCE_NODE_ID DEST_NODE_ID 
1    2 
1    3 
1    4 
2    1 
2    3 
+0

啊,CROSS APPLY,我以前見過它,但是無法將我的頭包裹在它的周圍......感謝您閃電般的快速反應! –

+0

@LouisSomers,很高興看到這個!你非常接近! Thx對於你的問題來說,複製你的查詢並不是什麼大不了的事,輸入更多的字母並放置答案......快樂編碼! – Shnugo