2012-12-25 5 views
1

나는 다음과 같은 XML이 :크로스 SQL 서버에서 XML에서 아이의 부모 값을 얻기 위해 적용

<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 %입니다. 다음은 교차 적용을 사용하는 나의 해결책입니다.

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