我有一张表,其中包含一个 XML 列XmlMsg
。此列可以包含orderstatus
、、vehiclestatus
...
我只对orderstatus
节点感兴趣,更确切地说对以下两种情况感兴趣:
- 最后一个
orderpart
是“待定”。 - 最后一个
orderpart
是“待定”,倒数第二个是“已完成”。
第一个例子如下(仅显示相关部分):
<orderstatus responsecode="0"
...
numberoforderparts="3">
...
<orderparts>
<orderpart orderpartnumber="1"/>
<orderpart orderpartnumber="2"/>
<orderpart orderpartnumber="3">
<eventtype>Pending</eventtype>
...
</orderpart>
</orderparts>
</orderstatus>
第二个示例如下(也只显示相关部分):
<orderstatus responsecode="0"
...
numberoforderparts="3">
...
<orderparts>
<orderpart orderpartnumber="1"/>
<orderpart orderpartnumber="2">
<eventtype>Completed</eventtype>
...
</orderpart>
<orderpart orderpartnumber="3">
<eventtype>Pending</eventtype>
...
</orderpart>
</orderparts>
</orderstatus>
我能够通过以下查询获取第一个列表:
SELECT *,
XmlMsg.value('(/orderstatus/@numberoforderparts)[1]', 'INT') AS NumberOfOrderParts,
-- Retrieve the last orderpart with eventtype="Pending"
XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] and eventtype="Pending"])[1]') AS LastOrderPart,
-- Retrieve the second-to-last orderpart with eventtype="Completed"
XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] - 1 and eventtype="Completed"])[1]') AS PreviousOrderPart
FROM
[dbo].[AWIMessageLogs]
WHERE
Source = 'RCV_RESP'
AND LogDateTime >= '2024-11-26'
AND LogDateTime <= '2024-11-26 15:00'
AND XmlMsg.exist('/orderstatus') = 1
-- Ensure that the last orderpart has eventtype="Pending"
AND XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] and eventtype="Pending"])[1]') IS NOT NULL
但是,我不知道如何获取第二个列表。
有人有想法吗?
通常使用节点方法更容易获得这些内容,例如:
然后,您可以使用一些 LAG/LEAD 来查找相关值或将数据放入临时表中并从那里进行处理。
输出:
您可以对这两个查询使用 XPath 1.0:
获取
orderstatus
最后一个节点的orderpart
位置"Pending"
:获取
orderstatus
最后一个节点orderpart
和"Pending"
倒数第二个节点"Complete"
:db<>fiddle (作者@Charlieface)