这个问题一直在我周五下午搞乱:
我有这个XML:
declare @xml as XML
set @xml =
'<fields>
<field>
<id>1</id>
<items>
<item>
<name>name1_1</name>
<value>value1_1</value>
</item>
<item>
<name>name1_2</name>
<value>value1_2</value>
</item>
</items>
</field>
<field>
<id>2</id>
<items>
<item>
<name>name2_1</name>
<value>value2_1</value>
</item>
<item>
<name>name2_2</name>
<value>value2_2</value>
</item>
</items>
</field>
</fields>'
使用T-SQL和XPath,我需要一个查询来获得这个结果:
id name value
1 name1_1 value1_1
1 name1_2 value1_2
2 name2_1 value2_1
2 name2_2 value2_2
我的名字和价值在于:
SELECT c.value('name[1]', 'nvarchar(255)') name,
c.value('value[1]', 'nvarchar(255)') value
FROM @xml.nodes('fields/field/items/item') t(c)
...但是如何插入父列“id”?
答案 0 :(得分:0)
假设:每id
只有一个field
元素。
SELECT c.value('../../id[1]', 'int') id,
c.value('name[1]', 'nvarchar(255)') name,
c.value('value[1]', 'nvarchar(255)') value
FROM @xml.nodes('fields/field/items/item') t(c)
..
运算符表示&#34;选择节点的父节点&#34;在XPATH中。因此,查询将选择item
的父级,然后选择items
的父级,然后选择第一个子级节点id
答案 1 :(得分:0)
您自己的代码使用.nodes()
从重复元素中获取派生表。在您的情况下,有两个级别的重复元素:
您必须使用.nodes()
两次:
SELECT fld.value(N'(id/text())[1]',N'int') AS FieldID
,itm.value(N'(name/text())[1]',N'nvarchar(max)') AS ItemName
,itm.value(N'(value/text())[1]',N'nvarchar(max)') AS ItemValue
FROM @xml.nodes(N'/fields/field') AS A(fld)
OUTER APPLY A.fld.nodes(N'items/item') AS B(itm);
第一个.nodes()
返回XML片段,每个字段一个,为每个字段片段调用第二个节点来选择它们的项目。
当您不希望看到没有OUTER APPLY
个节点的字段时,如果可能有没有<item>
个节点的字段和CROSS APPLY
,请使用<item>
(类似于LEFT JOIN
vs INNER JOIN
)