Skip to content
Advertisement

XQUERY -SQL Retrieve list of child and parent ID

How I can query the xml in order to obtain the following result? I am completely new on using XQuery.

XML sample:

<dec>
    <asi idAsig="1">
        <asiA  A_1="1" A_2="0" A_3="N" A_4="8" A_5="1589" A_6="160"/>
        <asiE1 E1_1="2569" E1_2="2569" E1_3="0" E1_4="0" E1_5="0"/>
    </asi>
    <asi  idAsig="2" >
        <asiA  A_1="1" A_2="0" A_3="N" A_4="8" A_5="7175" A_6="160"/>
        <asiB1 B1_1="1" B1_2="0" B1_3="N" B1_4="8" B1_5="4848"/>
        <asiB1 B1_1="52" B1_2="0" B1_3="N" B1_4="8" B1_5="625"/>
        <asiE1 E1_1="7175" E1_2="2512" E1_3="0" E1_4="0" E1_5="0"/>
    </asi>
    <asi idAsig="3" >
        <asiA  A_1="3" A_2="3" A_3="Y" A_4="10" A_5="585" A_6="160"/>
        <asiB1 B1_1="1" B1_2="0" B1_3="N" B1_4="8" B1_5="589"/>
        <asiB1 B1_1="39" B1_2="0" B1_3="N" B1_4="8" B1_5="15647"/>
        <asiE1 E1_1="7175" E1_2="2512" E1_3="0" E1_4="0" E1_5="0"/>
    </asi>
</dec>

And the result:

idAsig B1_1 B1_2 B1_3 B1_4 B1_5
1 NULL NULL NULL NULL NULL
2 1 0 N 8 4848
2 52 0 N 8 625
3 1 0 N 8 589
3 39 0 N 8 15647

I try this query

SELECT 
 [idAsig] = Y.A.value('(@idAsig)[1]', 'INT')
,[B1_1] = Y.A.value('(@B1_1)[1]', 'int')                                                        
,[B1_2] = e.XMLData.value('(/*:dec/*:asi/*:asiB1/@B1_2)[1]', 'int')
,[B1_3] =  Y.A.value('(@B1_3)[1]', 'NVARCHAR(MAX)')
,[B1_4] =  Y.A.value('(@B1_4)[1]', 'int')
,[B1_5] =  Y.A.value('(@B1_5)[1]', 'int')

FROM #tmp_XmlData AS e
--OUTER APPLY e.XMLData.nodes('/*:dec/*:asi') AS X(A)
CROSS APPLY e.XMLData.nodes('/*:dec/*:asi/*:asiB1') AS Y(A)

Advertisement

Answer

You can use CROSS APPLY on e.XMLData.nodes('/*:dec/*:asi') AS X(A) and then OUTER APPLY on X.A.nodes('*:asiB1') because you want all asi elements to appear in the query result regardless it has child asiB1 or not:

SELECT 
 [idAsig] = X.A.value('(@idAsig)[1]', 'INT')
,[B1_1] = Y.A.value('(@B1_1)[1]', 'int')                                                        
,[B1_2] = e.XMLData.value('(/*:dec/*:asi/*:asiB1/@B1_2)[1]', 'int')
,[B1_3] =  Y.A.value('(@B1_3)[1]', 'NVARCHAR(MAX)')
,[B1_4] =  Y.A.value('(@B1_4)[1]', 'int')
,[B1_5] =  Y.A.value('(@B1_5)[1]', 'int')

FROM tmp_XmlData AS e
CROSS APPLY e.XMLData.nodes('/*:dec/*:asi') AS X(A)
OUTER APPLY X.A.nodes('*:asiB1') AS Y(A)

dbfiddle.uk demo

Advertisement