【问题标题】:How do I calculate interval between two datetime2 columns (SQL Server)?如何计算两个 datetime2 列之间的间隔(SQL Server)?
【发布时间】:2013-10-21 14:36:47
【问题描述】:

您好,我正在尝试计算 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 个小数点的精度?谢谢。

【问题讨论】:

    标签: sql-server intervals datetime2


    【解决方案1】:

    您可以简单地使用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)
    

    【讨论】:

    • 计算两个科学指标的间隔。存储间隔值,然后将其添加到另一个 datetime2 以进行预测。虽然两个日期之间的差距通常不是那么大(在上面的示例中为 4 天)。也许这更现实一些。选择 DATEDIFF(MICROSECOND, cast('20010101 23:45:21.12347' as datetime2), cast('20010102 00:05:15.56786' as datetime2))
    • 它似乎在足够小的间隔内工作。也许只是要注意这种精度的微秒上限?如果只有 SQL 服务器 datetime2 在这方面的行为与 datetime 类似,那么我就不必经历这样的麻烦了。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2015-04-22
        • 2020-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-01
        • 2011-03-07
        • 1970-01-01
        相关资源
        最近更新 更多