问题
My prior question was solved here. Now I'm adding one more level of complexity to it - data that is nested parent, child, grandchild.
You can see and run sample here: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=df2766c95383d4c8c2d1f55539634341
Sample Code, where Leg1 might be the trip out, and Leg2 might be the trip back. Each leg can have one or more flights.
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)
The issue is that I'm still need 3 rows returned, but now I'm getting 6.
Expected result would be:
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 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Windows Server 2019 Standard 10.0 (Build 17763: )
回答1:
In the second apply, you want to be applying to the nodes from XmlData2.xmlDoc2
. The way you have it written, it looks for nodes from the root again, which will apply to all Flight
elements in the XML.
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);
来源:https://stackoverflow.com/questions/62008546/xml-column-three-levels-hierarchy-with-cross-apply