【问题标题】:Cross Apply to get child parent value from Xml in SQL Server交叉应用以从 SQL Server 中的 Xml 获取子父值
【发布时间】:2012-12-25 08:26:02
【问题描述】:

我有以下 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)

我无法获取包含父行值的第一列。 您能否建议我可以进行哪些更改以获得第一列的值?

【问题讨论】:

    标签: sql-server sql-server-2008 tsql cross-apply sqlxml


    【解决方案1】:

    试试这个:

    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 属性(@ 987654328@元素)

    【讨论】:

    • @Paresh:如果这个答案帮助你解决了你的问题,你应该accept this answer。这将表达您对花费自己的时间帮助您的人们的感激之情。
    • 非常有帮助! ../@value 建议有助于减少 CROSS'es :)。
    【解决方案2】:

    使用 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)
    

    【讨论】:

    • 查询成本只是一个估计值,当涉及到 XML 查询时,它是一个非常糟糕的估计值。但是在另一个答案中使用父轴对性能来说是灾难性的。使用交叉应用是执行此操作的方法。 +1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    相关资源
    最近更新 更多