Cross Apply pour get la valeur parent enfant à partir de Xml dans SQL Server

J'ai le XML suivant:

<root> <row value="US"> <col value="00">Jon</col> <col value="01">David</col> <col value="02">Mike</col> <col value="03">Nil</col> </row> <row value="Canada"> <col value="C1">Pollard</col> </row> <row value="Japan"> <col value="J1">Yin</col> <col value="J2">Li</col> </row> <row value="India"> <col value="MP">Ram</col> <col value="UP">Paresh</col> <col value="AP">Mohan</col> </row> </root> 

et je veux la sortie suivante en utilisant la requête SQL Server:

 US 00 Jon US 01 David US 02 Mike US 03 Nil Canada C1 Pollard Japan J1 Yin Japan J2 Li India MP Ram India UP Paresh India AP Mohan 

J'utilise la requête SQL suivante:

 declare @x xml set @x = '<root> <row value="US"> <col value="00">Jon</col> <col value="01">David</col> <col value="02">Mike</col> <col value="03">Nil</col> </row> <row value="Canada"> <col value="C1">Pollard</col> </row> <row value="Japan"> <col value="J1">Yin</col> <col value="J2">Li</col> </row> <row value="India"> <col value="MP">Ram</col> <col value="UP">Paresh</col> <col value="AP">Mohan</col> </row> </root>' select r.value('@value','varchar(100)'),r.value('.','varchar(100)') from @x.nodes('root') as m(c) cross apply mcnodes('row/col') as x(r) 

Je suis incapable d'get la première colonne qui contient la valeur de la ligne parent. Pouvez-vous me suggérer quels changements je peux faire pour get la valeur de la première colonne?

Essaye ça:

 select ParentValue = c.value('(../@value)[1]', 'varchar(100)'), ValueAttr = c.value('@value','varchar(100)'), ColValue = c.value('.','varchar(100)') from @x.nodes('/root/row/col') as m(c) 

Fondamentalement, il n'y a vraiment pas besoin d'utiliser CROSS APPLY du tout – il suffit de sélectionner les nœuds /root/row/col de l'appel .nodes() , et d'utiliser ../@value pour get l'atsortingbut value sur le nœud parent ( <row> élément)

L'utilisation de CROSS APPLY est plus efficace. Regardez le plan d'exécution, le coût de la requête est seulement de 16% lorsque CROSS APPLY est utilisé et de 84% lorsque aucune application CROSS n'est pas utilisée. Voici ma solution qui utilise CROSS APPLY:

 select Tcvalue('@value[1]','varchar(100)') as 'Country' ,T2.col.value('@value[1]','varchar(100)') as 'Col2' ,T2.col.value('data(.)','varchar(100)') as 'Col3' from @x.nodes('/root/row') T(c) CROSS APPLY Tcnodes('col') as T2(col)