如何计算两个datetime2列(SQL Server)之间的间隔?

时间:2013-10-14 03:54:09

标签: sql-server intervals datetime2

您好我正在尝试计算两列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

但是,当我将它投射到日期时间时,我正在失去精度(请注意上面的3位小数精度)。在这种情况下,我实际上需要全部5个小数点。有没有办法获得两个datetime2列之间的间隔,仍然保持5个小数点的精度?感谢。

3 个答案:

答案 0 :(得分:16)

您只需使用DateDiff

即可
  

返回指定datepart的count(有符号整数)   在指定的startdate和enddate之间交叉的边界。

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)

答案 1 :(得分:2)

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

select DATEDIFF(millisecond,'20010105 12:35:15.56786','20010101 23:45:21.12347') 

答案 2 :(得分:0)

5年后,这不太可能帮助奴隶制,但是这个冗长的例子可能满足了要求:

    @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;```