【问题标题】:XML Column - three levels hierarchy - with Cross ApplyXML 列 - 三级层次结构 - 交叉应用
【发布时间】:2020-05-25 18:31:50
【问题描述】:

我之前的问题已解决here。现在,我为其增加了一层复杂性——嵌套的父、子、孙数据。

您可以在此处查看和运行示例: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=df2766c95383d4c8c2d1f55539634341

示例代码,其中 Leg1 可能是外出行程,Leg2 可能是返回行程。每条腿可以有一个或多个航班。

DECLARE @xml XML='
<Reservation>
  <Name>Neal</Name>
    <Leg seq=''1''>
      <Flight>12</Flight>
    </Leg>
    <Leg seq=''2''>
      <Flight>34</Flight>
      <Flight>56</Flight>
    </Leg>
</Reservation>'
select @xml

DECLARE @xmlTable TABLE (
    xmlDoc Xml
);
Insert into @xmltable values (@xml)
--Select xmlDoc from @XmlTable 

Select xmlDoc.value('(//Name)[1]', 'varchar(30)') as Passenger,
       XmlData2.xmlDoc2.query('.') as XmlData2,
       XmlData2.xmlDoc2.value('./@seq', 'int') as LegSeq,
       XmlData3.xmlDoc3.query('.') as XmlData3,
       XmlData3.xmlDoc3.value('.', 'varchar(20)') as Flight
FROM @xmlTable as t
     CROSS APPLY 
        t.xmlDoc.nodes('//Leg') AS XmlData2(xmlDoc2)
     CROSS APPLY 
        t.xmlDoc.nodes('//Flight') AS XmlData3(xmlDoc3)

问题是我仍然需要返回 3 行,但现在我得到了 6 行。

预期结果是:

Neal LegSeq=1 Flight=12 
Neal LegSeq=2 Flight=34
Neal LegSeq=2 Flight=56

Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) Sep 24 2019 13:48:23 版权所有 (C) 2019 Microsoft Corporation Developer Edition (64-bit) o​​n Windows Server 2019 Standard 10.0 (Build 17763: )

【问题讨论】:

  • 嗨尼尔,请包括预期的输出。产生三行的方法有很多种,但这并不能描述您的输出真正需要的内容。
  • 添加了预期结果。我认为从问题和 XML 数据的层次结构中可以明显看出这一点。有一名乘客、两条航段和三个航班号。第一个航段有一个航班号,第二个航段有两个航班号。

标签: sql-server tsql sqlxml


【解决方案1】:

在第二个应用中,您希望从XmlData2.xmlDoc2 应用到节点。按照您编写的方式,它会再次从根中查找节点,这将应用于 XML 中的所有 Flight 元素。

DECLARE @xml XML='
<Reservation>
  <Name>Neal</Name>
    <Leg seq=''1''>
      <Flight>12</Flight>
    </Leg>
    <Leg seq=''2''>
      <Flight>34</Flight>
      <Flight>56</Flight>
    </Leg>
</Reservation>'
select @xml

DECLARE @xmlTable TABLE (
    xmlDoc Xml
);
Insert into @xmltable values (@xml)
--Select xmlDoc from @XmlTable 

Select xmlDoc.value('(//Name)[1]', 'varchar(30)') as Passenger,
       XmlData2.xmlDoc2.query('.') as XmlData2,
       XmlData2.xmlDoc2.value('./@seq', 'int') as LegSeq,
       XmlData3.xmlDoc3.query('.') as XmlData3,
       XmlData3.xmlDoc3.value('.', 'varchar(20)') as Flight
FROM @xmlTable as t
     CROSS APPLY 
        t.xmlDoc.nodes('//Leg') AS XmlData2(xmlDoc2)
     CROSS APPLY 
        XmlData2.xmlDoc2.nodes('Flight') AS XmlData3(xmlDoc3);

【讨论】:

  • 啊,我早该想到的。就像连接一样,每个交叉应用通常是不同的项目。
猜你喜欢
  • 2021-09-02
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多