交叉应用在不同的水平

时间:2015-01-01 00:02:58

标签: sql-server cross-apply

我有xml数据,如下所示:

<game> 

  <teams>
    <home id="363" color="000099">Brazil</home>
    <away id="375" color="c5b358">Germany</away>
  </teams>

  <gameInfo>
    <homeScore>1</homeScore>
    <awayScore>7</awayScore>
    <clock>90</clock>
  </gameInfo>

</game>

我想创建一个按以下顺序排列的表:home,away,homeID,awayID,homeScore,awayScore。我似乎无法将家庭ID(363和375)放入表中:

select *
from (
select 

e.value('(./teams/home/text())[1]', 'nvarchar(100)') home,
e.value('(./teams/away/text())[1]', 'nvarchar(100)') away,
e.value('./teams/home/@id', 'int') homeID,
e.value('./teams/away/@id', 'int') awayID
e.value('(./gameInfo/homeScore/text())[1]', 'int') homeScore,
e.value('(./gameInfo/awayScore/text())[1]', 'int') awayScore

from (select * from [XMLTest].[dbo].[MATCHES]) t
cross apply t.data.nodes('game') as t2(e)

) events

1 个答案:

答案 0 :(得分:2)

您错过了提及Id的位置。

value()始终需要positional引用来标识您想要的node

像这样更改select

SELECT e.value('(./teams/home/text())[1]', 'nvarchar(100)') home,
       e.value('(./teams/away/text())[1]', 'nvarchar(100)') away,
       e.value('(./teams/home/@id)[1]', 'int')              homeID,
       e.value('(./teams/away/@id)[1]', 'int')              awayID,
       e.value('(./gameInfo/homeScore/text())[1]', 'int')   homeScore,
       e.value('(./gameInfo/awayScore/text())[1]', 'int')   awayScore
FROM   [MATCHES] t
       CROSS apply t.data.nodes('game') AS t2(e) 

示例:

DECLARE @xml XML='<game> 

  <teams>
    <home id="363" color="000099">Brazil</home>
    <away id="375" color="c5b358">Germany</away>
  </teams>

  <gameInfo>
    <homeScore>1</homeScore>
    <awayScore>7</awayScore>
    <clock>90</clock>
  </gameInfo>

</game>'

SELECT cs.e.value('(./teams/home)[1]', 'nvarchar(100)') home,
       cs.e.value('(./teams/away)[1]', 'nvarchar(100)') away,
       cs.e.value('(./teams/home/@id)[1]', 'int')          homeID,
       cs.e.value('(./teams/away/@id)[1]', 'int')          awayID,
       cs.e.value('(./gameInfo/homeScore)[1]', 'int')   homeScore,
       cs.e.value('(./gameInfo/awayScore)[1]', 'int')   awayScore
FROM   @xml.nodes('game') AS cs (e) 

<强>结果:

home    away    homeID  awayID  homeScore   awayScore
------  ------- ------  ------  ---------   ---------
Brazil  Germany 363     375     1           7