DECLARE @Data AS XML = '
<Catalog>
<Artist>
<name>Wolfgang</name>
<name>Razorback</name>
</Artist>
<Album>
<Category>Rock</Category>
<Category>Alternative</Category>
</Album>
</Catalog>'
SELECT
B.value('(text())[1]','varchar(15)') as Artist,
C.value('(text())[1]','varchar(15)') as Album
FROM @Data.nodes('/Catalog') AS Catalog(A)
CROSS APPLY A.nodes('Artist/name') as Artist(B)
CROSS APPLY A.nodes('Album/Category') as Album(C)
我期待结果应该是这样的,我真的只想把艺术家作为第一列和专辑作为第二列
但是它返回了这个查询,
答案 0 :(得分:2)
;with cte_artist as (
select
row_number() over(order by (select '1')) as rn,
T.C.value('text()[1]','varchar(15)') as Artist
from @Data.nodes('/Catalog/Artist/name') as T(C)
), cte_album as (
select
row_number() over(order by (select '1')) as rn,
T.C.value('text()[1]','varchar(15)') as Album
from @Data.nodes('/Catalog/Album/Category') as T(C)
)
select
a1.Artist,
a2.Album
from cte_artist as a1
full outer join cte_album as a2 on a2.rn = a1.rn
<强> sql fiddle demo 强>
但更好的方法是创建像这样的xml(或任何其他你想要的嵌套方式):
<Catalog>
<Album name="Rock album">
<Category>Rock</Category>
<Artist name="Wolfgang"/>
</Album>
<Album name="Alternative album">
<Category>Alternative</Category>
<Artist name="Razorback"/>
</Album>
</Catalog>
所以你可以像这样查询:
select
T.C.value('@name','varchar(15)') as name,
T.C.value('(Category/text())[1]','varchar(15)') as Category,
T.C.value('Artist[1]/@name','varchar(15)') as Artist
from @Data.nodes('/Catalog/Album') as T(C)