Не имея возможности тестировать столько строк, сколько у вас есть, я дам вам этот скрипт для проверки ( fiddle <> ):
DECLARE @x XML=N'
<Level1><Level2 name="l2_name"><Level3 name="l3_name">
<Level4 name="l4_name"><Level5 name="l5_name">
<Level6 name="l6_name" value="l6_value"/>
<Level6 name="l6_name" value="l6_value"/>
</Level5></Level4></Level3></Level2></Level1>';
SELECT
x.n.value('../../../../@name', 'varchar(20)') as [col1],
x.n.value('../../../@name', 'varchar(20)') as [col2],
x.n.value('../../@name', 'varchar(20)') as [col3],
x.n.value('../@name', 'varchar(20)') as [col4],
x.n.value('./@name', 'varchar(20)') as [col5]
FROM
@x.nodes('/Level1/Level2/Level3/Level4/Level5/Level6') AS x(n);
Это будет явнозапрос для Level6
узлов, затем возврат к значениям атрибутов родителей.Это, скорее всего, быстрее, чем перекрестное применение запросов для каждого отдельного элемента LevelN
.
Обновлено, для элементов уровня 6 с разными именами и при условии, что только один такой элемент каждого имени появляется как потомокуровень 5:
DECLARE @x_2 XML=N'<Level1>
<Level2 name="l2_name">
<Level3 name="l3_name">
<Level4 name="l4_name">
<Level5 name="l5_name">
<Level6_1 name="l6_1_name" value="l6_1_value"/>
<Level6_2 name="l6_2_name" value="l6_2_value"/>
</Level5></Level4></Level3></Level2></Level1>';
SELECT
x.n.value('../../../@name', 'varchar(20)') as [col1],
x.n.value('../../@name', 'varchar(20)') as [col2],
x.n.value('../@name', 'varchar(20)') as [col3],
x.n.value('./@name', 'varchar(20)') as [col4],
x.n.value('(./Level6_1/@name)[1]', 'varchar(20)') as [col5],
x.n.value('(./Level6_2/@name)[1]', 'varchar(20)') as [col6]
FROM
@x_2.nodes('/Level1/Level2/Level3/Level4/Level5') AS x(n);
Выбирает узлы на уровне 5, возвращает родительские атрибуты для родительских атрибутов, затем выбирает дочерние элементы на основе имени.Выбирает первый такой элемент, используя селектор [1]
.