我试图在 sql 脚本中获取 xml 特定元素的位置,但我正在获取特定元素的所有位置的详细信息,因为我只是在寻找特定级别.
I am trying to get position of a specific element of xml in sql script , but I am getting details for all the positions of a specific element , where as I am looking for a particular level only.
这是代码:
declare @xmlVar xml ='
<A specVersion="2.09">
<B id="1" type="Regular">
<C>
<D>
<E actioncode="A" date="06/13/2018 09:20" />
<E actioncode="B" date="06/13/2018 09:20" />
</D>
<D>
<E actioncode="C" date="06/13/2018 09:20" />
</D>
</C>
</B>
<B id="2" type="Regular">
<C>
<D>
<E actioncode="D" date="06/13/2018 09:20" />
</D>
</C>
<F>
<D>
<E actioncode="F" date="06/13/2018 09:20" />
</D>
</F>
</B>
</A>' ;
WITH Tally(Nmbr) AS
(
SELECT TOP (SELECT @xmlVar.value(N'count(//D)','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'@actioncode[1]','nvarchar(max)') AS Employee
FROM Tally
OUTER APPLY(SELECT @xmlVar.query(N'//D').query(N'/D[sql:column("Nmbr")]')) AS B(ds)
OUTER APPLY ds.nodes(N'D/E') AS C(e);
以上查询的结果:
1 A
1 B
2 C
3 D
4 F
预期输出:
1 A
1 B
2 C
3 D
我正在寻找路径 A->B->C->D 中所有 D 的位置,而不是其他路径中的位置.
I am looking for positions of all D which comes in path A->B->C->D not the one's which come in other path.
好的,对于您之前的问题,这似乎是一个相当容易的更改.您可以使用相同的逻辑,但将其缩减为您想要查看的路径:
Okay, this seems to be a rather easy change to your previous question. You can use the same logic, but reduce it to the path you want to see:
WITH Tally(Nmbr) AS
(
SELECT TOP (SELECT @xmlVar.value(N'count(/A/B/C/D)','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'@actioncode[1]','nvarchar(max)') AS Employee
FROM Tally
OUTER APPLY(SELECT @xmlVar.query(N'/A/B/C/D').query(N'/D[sql:column("Nmbr")]')) AS B(ds)
OUTER APPLY ds.nodes(N'D/E') AS C(e);
值正如您所发现的,上述方法不能向后移动到 .试试这个:
WITH AllBs AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS B_position
,b.value('@id','int') AS B_id
,b.query('.') AS B_node
FROM @xmlVar.nodes('/A/B') AS A(b)
)
,AllDs As
(
SELECT AllBs.*
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS D_position
,d.query('.') AS D_node
FROM AllBs
OUTER APPLY B_node.nodes('B/C/D') AS A(d)
)
SELECT AllDs.*
,e.value(N'@actioncode[1]','nvarchar(max)') AS Employee
FROM AllDs
OUTER APPLY D_node.nodes('D/E') AS A(e);
正如我在第一个答案中所写的,排序顺序存在很小的风险......但是使用 tally 表 的方法无法获取第三次出现,因为 [sql:column()] 与任何父项重新编号.这意味着:第三个 是第二个 中的第一个.这就是为什么我将 .query() 放在中间......
As written in my first answer, there's a tiny risk about the sort order... But the approach with the tally table cannot fetch the 3rd occurance, because the position within [sql:column()] is re-numbered with any parent. That means: The 3rd <D> is the 1st in the 2nd <B>. That's why I placed the .query() in between...
这篇关于XML 到 SQL 的问题 - SQL Server的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
将每个子标记转换为具有多个分隔符的单列-SQLConverting Every Child Tags in to a Single Column with multiple Delimiters -SQL Server (3)(将每个子标记转换为具有多个分隔符的单列-SQ
如何从多个表创建视图?How can I create a view from more than one table?(如何从多个表创建视图?)
根据前一行内的计算值创建计算值Create calculated value based on calculated value inside previous row(根据前一行内的计算值创建计算值)
如何将表格的前两列堆叠成一列,但也仅将第三How do I stack the first two columns of a table into a single column, but also pair third column with the first column only?(如何将表格的前两列堆
递归 t-sql 查询Recursive t-sql query(递归 t-sql 查询)
将月份名称转换为日期/月份编号(问题和答案的组Convert Month Name to Date / Month Number (Combinations of Questions amp; Answers)(将月份名称转换为日期/月份编号(问题和答案的组合