日期类型的XML后代的MIN

时间:2016-08-08 21:03:46

标签: sql-server xml tsql xquery-sql

如何在XML字段中查询所有后代的最小日期。像这样:

DECLARE @xml XML ='
<Plan>
    <EffectiveDate>2006-01-01</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
</Plan>'

SELECT @xml.value('min(descendant::EffectiveDate)','varchar(max)') minDate
    ,@xml.value('count(descendant::EffectiveDate)','varchar(max)') countDate

不幸的是上面为MIN返回NULL

3 个答案:

答案 0 :(得分:4)

非类型化xml节点值的默认数据类型为xdt:untypedAtomic。 m in Function (XQuery)会尝试将xdt:untypedAtomic值转换为xs:double,然后返回最小值。您的值无法转换为xs:double,因此min()将返回四个null值的最小值。

由于min()xs:date上工作得很好,您可以先将值转换为xs:date,然后对日期值执行min()

declare @xml xml = '
<Plan>
    <EffectiveDate>2006-01-01</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
</Plan>';

select @xml.value('min(for $n in descendant::EffectiveDate/text() 
                       return $n cast as xs:date?)', 'date'),
       @xml.value('count(descendant::EffectiveDate)', 'int');

答案 1 :(得分:3)

最简单的方法:

DECLARE @xml XML ='
<Plan>
    <EffectiveDate>2006-01-01</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
</Plan>'

SELECT  MIN(t.v.value('.','date')) minDate,
        COUNT(t.v.value('.','date')) countDate
FROM @xml.nodes('//Plan/EffectiveDate') as t(v)

输出:

minDate     countDate
2006-01-01  4

答案 2 :(得分:2)

试试这个。我不认为这是最好的解决方案(我期待在这里看到更好的解决方案)。但它会给你你想要的东西。 已编辑(我更喜欢的第二个)

mypdfviewctrl.SetAnnotationEditPermissionHandler(edit_annot_proc, null);

这是第一个。

DECLARE @x XML ='
<Plan>
    <EffectiveDate>2006-01-01</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
    <EffectiveDate>2016-09-14</EffectiveDate>
</Plan>';

SELECT
    Min(a.EffDate) AS MinDate
    , Count(a.EffDate) AS CountDate
FROM
(
    SELECT
        EffDate.value('.','DATE') AS EffDate
    FROM
        @x.nodes('/Plan/EffectiveDate') AS Plans(EffDate)
)a;