我在SQL中有XML,我希望查询得到以下结果。
TabSeq | 路径 | SubTabSeq|
---|---|---|
1 | //Tab/系列 | 1|
1 | //选项卡/位置2 | |
2 | //Tab/地址 | 1 |
2 | //Tab/保险 |
在第二个查询中,您正在迭代子节点,因此您需要引用这些节点的父节点,即Tab。与这两种方法一样(取决于您想要的严格程度(:
SELECT
TabSeq1 = t.c.value('../@sequence', 'nvarchar(100)'),
TabSeq2 = t.c.value('./parent::Tab/@sequence', 'nvarchar(100)'),
'//Tab' + '/' + c.value('local-name(.)[1]','nvarchar(100)') AS Path,
t.c.value('@sequence', 'nvarchar(100)') As SubTabSeq
FROM @xml.nodes('//Tab/child::node()') as t(c)
请尝试以下解决方案。
SQL
declare @xml XML =
N'<Tabs>
<Tab sequence="001">
<Family sequence="001">
<Data>Yes</Data>
</Family>
<Location sequence="002">
<Data>USA</Data>
</Location>
</Tab>
<Tab sequence="002">
<Address sequence="001">
<Data>XYZ</Data>
</Address>
<Insurance sequence="002">
<Data>Yes</Data>
</Insurance>
</Tab>
</Tabs>';
SELECT c.value('for $i in . return count(../../*[. << $i])', 'INT') AS [TabSeq]
, '//Tab/' + c.value('local-name(.)','nvarchar(100)') AS Path
, t.c.value('@sequence', 'INT') As SubTabSeq
FROM @xml.nodes('/Tabs/Tab/*') as t(c);
输出
TabSeq | 路径 | SubTabSeq|
---|---|---|
1 | //Tab/系列 | 1|
1 | //选项卡/位置2 | |
2 | //Tab/地址 | 1 |
2 | //Tab/保险 |
如上所述,您得到了错误的sequence
属性。
您可以使用CROSS APPLY
将一个.nodes
调用的结果馈送到另一个,因此您可以首先分解Tab
节点,然后分解子节点
declare @xml xml='<Tabs><Tab sequence="001"><Family sequence="001"><Data>Yes</Data></Family><Location sequence="002"><Data>USA</Data></Location></Tab><Tab sequence="002"><Address sequence="001"><Data>XYZ</Data></Address><Insurance sequence="002"><Data>Yes</Data></Insurance></Tab></Tabs>'
SELECT
TabSeq1 = t2.child.value('@sequence', 'nvarchar(100)'),
TabSeq2 = t1.tab.value('@sequence', 'nvarchar(100)'),
Path = '/Tabs/Tab/' + t2.child.value('local-name(.)','nvarchar(100)'),
Data = t2.child.value('(Data/text())[1]', 'nvarchar(100)')
FROM @xml.nodes('/Tabs/Tab') t1(tab)
CROSS APPLY t1.tab.nodes('*') as t2(child)
db<gt;小提琴
请注意,//
子轴速度较慢,应使用/
子轴。