2016-07-06 13 views
2

Ich benutze Microsoft SQL Server.SQL Abfrage hierarchische XML mit mehreren Unterelementen

Ich habe eine einfache Hierarchie wie ein gerichteten Graphen in Xml:

wie diese
SOURCE_NODE_ID | DEST_NODE_ID 
1    | 2 
1    | 3 
1    | 4 
2    | 1 
2    | 3 

Eine Abfrage:

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); 

Meine gewünschte Ausgabe wie folgt eine Tabelle wäre

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); 

Gibt nur die zurück erste Flanke:

SOURCE_NODE_ID | DEST_NODE_ID 
1    | 2 
2    | 1 

Dies tut ein wenig besser:

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); 

Nur verkettet es alle Kanten in einer Zelle:

SOURCE_NODE_ID | DEST_NODE_ID 
1    | 234 
2    | 13 

Wie kann ich mein gewünschtes Ergebnis? Sollte ich mich einer inneren Frage oder etwas anschließen? Wahrscheinlich mache ich es zu kompliziert, sicherlich gibt es dafür eine einfache Lösung?

+0

Dies ist eine gute Frage: Copy'n'pasteable Testcode, eigene Anstrengung, erwartete Ausgabe, klare Erklärung .. Wenn nur alle Fragen so wären :-) Stimm es hoch! – Shnugo

Antwort

4

Probieren Sie es wie diese

Da es sehr viele NODE Elemente sind, müssen Sie .nodes() für sie nennen. Da es viele verschachtelte EDGE Elemente gibt, müssen Sie CROSS APPLY .nodes() für sie aufrufen.

Der Rest ist einfach ...

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) 

Das Ergebnis

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

Ah, CROSS APPLY, ich hatte es schon vorher gesehen, aber ich konnte meinen Kopf noch nicht umschließen ... Danke für deine blitzschnelle Antwort! –

+0

@LouisSomers, froh, das zu lesen! Du warst sehr nah dran! Danke an deine gute Frage, es war keine große Sache, deine Anfrage zu kopieren, noch ein paar Buchstaben einzugeben und die Antwort zu platzieren ... Happy Coding! – Shnugo

Verwandte Themen