2012-12-25 24 views
1

我有下面的XML:跨應用從XML獲得SQL Server中的孩子父值

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

,我通過使用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 

我使用以下SQL查詢:

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 m.c.nodes('row/col') as x(r) 

我無法獲得第一列包含父行的值。 你能否建議我可以做些什麼改變來獲得第一列值?

回答

8

試試這個:

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) 

基本上,真的沒有必要使用CROSS APPLY在所有 - 只需從.nodes()呼叫/root/row/col節點,並使用../@value獲取父節點上的value屬性(在<row>元件)

+0

謝謝。這是工作。 – Paresh

+2

@Paresh:如果這個答案幫助你解決了你的問題,你應該[**接受這個答案**](http://meta.stackexchange.com/q/5234/153998)。這將表明你對那些花時間幫助你的人表示感謝。 –

+2

非常有幫助! ../@value建議有助於減少CROSS' :)。 – Willmore

3

使用CROSS APPLY更有效。查看執行計劃,使用CROSS APPLY時查詢成本僅爲16%,未使用CROSS APPLY時查詢成本爲84%。 這是我使用CROSS APPLY的解決方案:

select 
T.c.value('@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 T.c.nodes('col') as T2(col) 
+1

查詢成本只是一個估計值,當涉及到XML查詢時,這是一個非常糟糕的估計。但如果在其他答案中使用父軸,則會對性能產生災難性影響。使用交叉應用是這樣做的方法。 +1。 –

相關問題