我试图在使用 sql 选择值时获取 xml 节点的索引:
这是代码:
declare @myxml xml ='
<Departments>
<Department>
<Employee>
A
</Employee>
<Employee>
B
</Employee>
</Department>
<Department>
<Employee>
C
</Employee>
<Employee>
D
</Employee>
</Department>
</Departments>'
Select Emp = m.value('.','varchar(30)')
from @myxml.nodes('Departments/Department/Employee') X(m)
Run Code Online (Sandbox Code Playgroud)
上述查询的输出:
Emp
A
B
C
D
Run Code Online (Sandbox Code Playgroud)
预期输出:
Emp Department_Index
A 1
B 1
C 2
D 2
Run Code Online (Sandbox Code Playgroud)
即我想要与部门下每个员工相对应的部门索引。这里员工A和B属于部门第一部门,员工C和D属于部门第二部门。
所以我希望这将复杂的 XML 子项与没有唯一键的父项连接起来。
这是一个解决方案,我声称它适用于所有场景 - 尽管不能保证绑定到节点的数字<Department>将ROW_NUMBER()反映其在每种情况下的真实位置(请参阅下面的注释和链接):
declare @myxml xml ='
<Departments>
<Department>
<Employee>
A
</Employee>
<Employee>
B
</Employee>
</Department>
<Department>
<Employee>
C
</Employee>
<Employee>
D
</Employee>
</Department>
</Departments>';
Run Code Online (Sandbox Code Playgroud)
--查询将使用CTE将数字绑定到第一层并整体传递内部节点。最终的 SELECT 将使用传递过来的<Department>节点并选择其员工:
declare @myxml xml ='
<Departments>
<Department>
<Employee>
A
</Employee>
<Employee>
B
</Employee>
</Department>
<Department>
<Employee>
C
</Employee>
<Employee>
D
</Employee>
</Department>
</Departments>';
Run Code Online (Sandbox Code Playgroud)
如果您想了解排序顺序的保证,您可以阅读此线程。特别值得一读:John Cappellettis 回答下面的聊天。在那里,我提供了一种使用 的方法XQuery,以及另一种使用计数/数字表来选择元素所在位置的方法。但这是相当复杂和缓慢的。
这种方法将即时创建一个计数表。如果你有一个数字表那就更好了......
该TOP子句将将此计数限制为实际的<Department>节点数。请务必使用源表(我使用master..spt_values),该表至少具有您可能需要的行数。
第一个应用将.query()与 一起使用sql:column()以获得每个号码的正确部门节点。第二个申请将读取相关员工。
WITH Tally(Nmbr) AS
(
SELECT TOP (SELECT @myxml.value(N'count(/Departments/Department)','int'))
ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
FROM master..spt_values --just a pre-filled table with many rows
)
SELECT Nmbr
,e.value(N'text()[1]','nvarchar(max)') AS Employee
FROM Tally
OUTER APPLY(SELECT @myxml.query(N'/Departments/Department[sql:column("Nmbr")]')) AS A(ds)
OUTER APPLY ds.nodes(N'Department/Employee') AS B(e);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2628 次 |
| 最近记录: |