在我的交易表中,我有一个XML列,其中包含有关交易的一些其他信息,例如如何计算交易中的某些价格(对于发布商方和卖方方)。由于计算算法可能改变,因此可以多次计算交易。完整的计算历史记录保存在XML中。
现在我想要获得最近计算算法的修订号。 XML结构如下所示:
<DataItems>
<!-- ... more data here ... -->
<CalculationHistory>
<Seller Revision="3" Time="2013-10-22T10:00:18.6294944Z" Result="20">
<Step Index="0" NodeId="c3e33dd5-25e0-4272-8b6f-f65fb2f0659b">bla</Step>
<Step Index="1" NodeId="b76b0915-7527-4df4-8185-5a425e723491">bla</Step>
<Step Index="2" NodeId="7e51947e-85ef-431f-8a21-9f4e30136805">bla</Step>
<Step Index="3" NodeId="10212fe9-8378-463d-b35b-27225b3cf2a1">bla</Step>
</Seller>
<Seller Revision="4" Time="2013-10-22T14:54:53.974548Z" Result="20">
<Step Index="0" NodeId="c3e33dd5-25e0-4272-8b6f-f65fb2f0659b">bla</Step>
<Step Index="1" NodeId="b76b0915-7527-4df4-8185-5a425e723491">bla</Step>
<Step Index="2" NodeId="7e51947e-85ef-431f-8a21-9f4e30136805">bla</Step>
<Step Index="3" NodeId="10212fe9-8378-463d-b35b-27225b3cf2a1">bla</Step>
</Seller>
<Publisher Revision="7" Time="2013-10-22T14:54:53.9794031Z" Result="40">
<Step Index="0" NodeId="2ce85808-903f-40b0-b8a9-c72e02d36d71">bla</Step>
<Step Index="1" NodeId="50ca67cc-5df8-450d-06d9-72c224027406">bla</Step>
<Step Index="2" NodeId="b2122e9f-c15b-4fa8-ce22-3dc73933d3d3">bla</Step>
</Publisher>
</CalculationHistory>
</DataItems>
所以我尝试的是选择最新的修订版号作为这样的列:
SELECT XmlColumn.value('(/DataItems/CalculationHistory/Seller[@Time = max(/DataItems/CalculationHistory/Seller/@Time)]/@Revision)[1]', 'int') AS SellerRevision FROM Transactions
但每次都会返回null
。我发现问题是max()
函数返回null
,即使在这种情况下:
SELECT XmlColumn.query('max(/DataItems/CalculationHistory/Seller/@Time)') FROM Transactions
...虽然用max
替换data
会返回正确的时间戳。
所以我猜我没有正确使用max
功能,但我做错了什么?
答案 0 :(得分:1)
奇怪的是,max
对字符串属性/元素不起作用:
select (select cast('<A D="1"/>' as xml)).query('max(/A/@D)')
-- returns 1
select (select cast('<A D="a"/>' as xml)).query('max(/A/@D)')
-- returns nothing
一些解决方法可能是使用变量:
declare @Time nvarchar(max)
select @Time = max(T.C.value('@Time', 'nvarchar(max)'))
from @Data.nodes('DataItems/CalculationHistory/Seller') as T(C)
select @Data.value('(/DataItems/CalculationHistory/Seller[@Time=sql:variable("@Time")]/@Revision)[1]', 'int')
<强> sql fiddle demo 强>
我稍后会尝试检查是否可以在SQL Server xpath
中使用max on strings