16

您好我正在尝试计算两列 datetime2 类型之间的差异。

但是 SQL server (2012) 似乎不喜欢以下内容:

select cast ('2001-01-05 12:35:15.56786' as datetime2)
    - cast ('2001-01-01 23:45:21.12347' as datetime2);

Msg 8117, Level 16, State 1, Line 2
Operand data type datetime2 is invalid for subtract operator.

现在,如果我将它转换为日期时间类型,它就可以工作:

select cast (cast ('2001-01-05 12:35:15.56786' as datetime2) as datetime) 
    - cast (cast ('2001-01-01 23:45:21.12348' as datetime2) as datetime);

1900-01-04 12:49:54.443

但是,当我将它转换为 datetime 时,我失去了精度(注意上面的 3 位小数精度)。在这种情况下,我实际上需要所有 5 个小数点。有没有办法获得两个 datetime2 列之间的间隔并且仍然保持 5 个小数点的精度?谢谢。

4

3 回答 3

23

您可以简单地使用DateDiff

返回指定开始日期和结束日期之间跨越的指定日期部分边界的计数(有符号整数)。

select DATEDIFF(MILLISECOND, cast('20010101 23:45:21.12347' as datetime2), 
                             cast('20010105 12:35:15.56786' as datetime2))

不幸的是,试图通过以下方式获得所需的精度:

select DATEDIFF(MICROSECOND, cast('20010101 23:45:21.12347' as datetime2), 
                             cast('20010105 12:35:15.56786' as datetime2)) 

导致溢出错误:

The datediff function resulted in an overflow. 
The number of dateparts separating two date/time instances is too large. 
Try to use datediff with a less precise datepart.

实现您想要的精度的一种方法是迭代分解成细粒度的时间组件(天、小时、分钟、秒等)并使用 DateAdd() 从值中减去它,例如

remainingAtLowerGranularity = DateAdd(granularity, -1 * numFoundInStep, value)
于 2013-10-14T03:59:55.020 回答
3

要查找两个日期之间的差异,您需要使用函数DATEDIFF

select DATEDIFF(millisecond,'20010105 12:35:15.56786','20010101 23:45:21.12347') 
于 2013-10-14T03:59:51.423 回答
0

5 年后,这不太可能帮助 slavoo,但这个冗长的例子可能满足了我们的要求:

    @FromDateTime DATETIME2 = CAST('20010101 23:45:21.12347' AS DATETIME2),
    @ToDateTime DATETIME2 = CAST('20010105 12:35:15.56786' AS DATETIME2),
    @FromMicroSecs NUMERIC,
    @FromDateTimeNoMicroSecs DATETIME,
    @ToMicroSecs NUMERIC,
    @ToDateTimeNoMicroSecs DATETIME;

SELECT
    @FromMicroSecs = DATEPART(MICROSECOND, @FromDateTime),
    @FromDateTimeNoMicroSecs = CAST(DATEADD(MICROSECOND, -1 * @FromMicroSecs, @FromDateTime) AS DATETIME),
    @ToMicroSecs = DATEPART(MICROSECOND, @ToDateTime),
    @ToDateTimeNoMicroSecs = CAST(DATEADD(MICROSECOND, -1 * @ToMicroSecs, @ToDateTime) AS DATETIME);

SELECT
    CAST(DATEDIFF(SECOND, @FromDateTimeNoMicroSecs, @ToDateTimeNoMicroSecs) AS NUMERIC) * 1000000 + @ToMicroSecs - @FromMicroSecs AS AnswerInMicroseconds;```
于 2019-08-05T08:02:44.017 回答