Попробуйте следующее решение. Он использует несколько предложений CROSS APPLY
для имитации отношений и предложение UNION ALL
для формирования различных XML фрагментов в желаемый результат.
SQL
DECLARE @xml XML =
N'<xml>
<registernumber>12</registernumber>
<language name="English">
<RegularTests>
<RegularTest Id="05-division">
<group>05-Counts</group>
<group>06-Counts</group>
<group>07-Counts</group>
</RegularTest>
<RegularTest Id="08-division">
<group>08-Counts</group>
</RegularTest>
<RegularTest Id="09-division">
<group>09-Counts</group>
</RegularTest>
</RegularTests>
<groups>
<group key="05-Counts">
<word Dated="03/20/2014">A</word>
<word Dated="03/20/2014">B</word>
</group>
<group key="08-Counts">
<word Dated="03/20/2014">C</word>
<word Dated="03/20/2014">D</word>
</group>
<group key="09-Counts">
<word Dated="03/20/2014">E</word>
<word Dated="03/20/2014">F</word>
<word Dated="03/20/2014">G</word>
</group>
</groups>
</language>
<language name="Japanese">
<RegularTests>
<RegularTest Id="05-division">
<group>05-Counts</group>
</RegularTest>
<RegularTest Id="08-division">
<group>08-Counts</group>
</RegularTest>
<RegularTest Id="09-division">
<group>09-Counts</group>
</RegularTest>
</RegularTests>
<groups>
<group key="05-Counts">
<word Dated="03/20/2014">か</word>
</group>
<group key="08-Counts">
<word Dated="03/20/2014">か</word>
<word Dated="03/20/2014">か</word>
<word Dated="03/20/2014">か</word>
</group>
<group key="09-Counts">
<word Dated="03/20/2014">か</word>
<word Dated="03/20/2014">か</word>
</group>
</groups>
</language>
<language name="Spanish">
<RegularTests>
<RegularTest Id="05-division">
<group>05-Counts</group>
</RegularTest>
<RegularTest Id="08-division">
<group>08-Counts</group>
</RegularTest>
<RegularTest Id="09-division">
<group>09-Counts</group>
</RegularTest>
</RegularTests>
<groups>
<group key="05-Counts">
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
</group>
<group key="08-Counts">
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
</group>
<group key="09-Counts">
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
<word Dated="09/19/2013">Д</word>
</group>
</groups>
</language>
</xml>';
SELECT @xml.value('(/xml/registernumber/text())[1]','INT') AS registernumber
, c.value('@name','VARCHAR(30)') AS [language]
, test.value('@Id','VARCHAR(30)') AS [RegularTest_Id]
, grp.value('(./text())[1]','VARCHAR(30)') AS [RegularTest_Group]
, NULL AS [group_key]
, NULL AS [word_Date]
, NULL AS [word]
FROM @xml.nodes('/xml/language') AS t(c)
CROSS APPLY t.c.nodes('RegularTests/RegularTest') AS z(test)
CROSS APPLY z.test.nodes('group') AS zz(grp)
UNION ALL
SELECT @xml.value('(/xml/registernumber/text())[1]','INT') AS registernumber
, c.value('@name','VARCHAR(30)') AS [language]
, NULL AS [RegularTest_Id]
, NULL AS [RegularTest_Group]
, gr.value('@key','VARCHAR(30)') AS [group_key]
, w.value('@Dated','VARCHAR(30)') AS [word_Date]
, w.value('(./text())[1]','VARCHAR(30)') AS [word]
FROM @xml.nodes('/xml/language') AS t(c)
CROSS APPLY t.c.nodes('groups/group') AS y(gr)
CROSS APPLY y.gr.nodes('word') AS w(w)
ORDER BY 2, 3 DESC, 5;