【问题标题】:Rounding Datetime to nearest 15 minutes in SQL Server在 SQL Server 中将日期时间四舍五入到最近的 15 分钟
【发布时间】:2015-11-26 11:57:38
【问题描述】:

我在 SQL Server 中遇到了舍入 datetime 的问题。我在rec_datetime 列中得到了datetime,但我想在一个新列r_datetime 中舍入这个datetime,对于整列rec_datetime,它必须舍入到最接近的15 分钟。

示例:

  • [2015-11-24 19:06:00.000] - 预期结果 -> [2015-11-24 19:00:00.000]
  • [2015-11-24 19:09:00.000] - 预期结果 -> [2015-11-24 19:15:00.000]

是否可以通过选择整列对其进行舍入?类似的东西:

select round(rec_datetime.......

【问题讨论】:

标签: sql-server datetime rounding


【解决方案1】:

向下舍入、最近舍入和向上舍入到最近的 15 分钟

DATEADD( minute, ( DATEDIFF( minute, 0,                                   dateTimeX   ) / 15 ) * 15, 0 ) AS dateTimeRoundDown
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( second, ( 15 * 60 ) / 2, dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundNearest
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute,   15           , dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundUp  

四舍五入

DATEADD( minute, ( DATEDIFF( minute, 0, dateTimeX ) / 15 ) * 15, 0 ) AS dateTimeRoundDown

以分钟为单位获取偏移量(自基准日期以来的分钟数):

DATEDIFF( minute, 0, dateTimeX )

通过整数除法向下舍入到 15 分钟块:

DATEDIFF( minute, 0, dateTimeX ) / 15 ) * 15

以分钟为单位添加基准日期:

DATEADD( minute, ( DATEDIFF( minute, 0, dateTimeX ) / 15 ) * 15, 0 )

最近的圆形

DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( second, ( 15 * 60 ) / 2, dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundNear

15 / 2 分钟添加到偏移量。

由于整数除法,需要以秒为单位。

总结

DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute, 15, dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundUp  

15 分钟添加到偏移量

基准日期

我通常使用 0 为基准日期,即 SQL Server 'epoch'

SELECT DATEADD( minute, 0, 0 ) -- '1900-01-01 00:00:00.000'

由于 DATEADD() & DATEDIFF() 使用 SQL Server 数据类型 INT(32 位)作为参数,对于很远的将来的日期,这可能会导致溢出。

使用另一个固定日期,例如“2010-01-01”,将避免溢出。

所选基准日期的时间部分必须为 00:00:00

使用基日期和整数除法,不需要强制转换和浮点运算。

单元测试

DECLARE @start DATETIME  = '2017-04-20 21:00:00'
DECLARE @end   DATETIME  = '2017-04-20 22:00:00'

;WITH CTE_dateTimes AS
(
    SELECT @start AS dateTimeX
    UNION ALL
    SELECT DATEADD( minute, 1, dateTimeX )
    FROM CTE_dateTimes
    WHERE DATEADD( minute, 1, dateTimeX ) <= @end
)
SELECT dateTimeX,
   DATEADD( minute, ( DATEDIFF( minute, 0,                                   dateTimeX   ) / 15 ) * 15, 0 ) AS dateTimeRoundDown,
   DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( second, ( 15 * 60 ) / 2, dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundNearest,
   DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute,   15           , dateTimeX ) ) / 15 ) * 15, 0 ) AS dateTimeRoundUp

FROM CTE_dateTimes

【讨论】:

    【解决方案2】:

    试试这样的:

    SELECT
      dateadd(minute, datediff(minute, '1999-12-31 23:52:30', col) / 15*15, '2000-01-01')
    FROM (values('2015-11-24 19:06:00.000'),('2015-11-24 19:09:00.000')) x(col)
    

    结果:

    2015-11-24 19:00:00.000
    2015-11-24 19:15:00.000
    

    【讨论】:

      【解决方案3】:

      在这种情况下,您需要将分钟四舍五入到最接近的 15

      尝试这样的查询:

      SELECT
      
       original_datetime
      
       --: this will give you the minute part
       , datepart(minute, original_datetime) AS minuteFromDate
      
       --: now get the nearest minute part to 15min, round it nearest to 15
       , round(datepart(minute, original_datetime)  * 1.0 / 15 , 0) * 15.0 AS roundedToNearest15
      
       -- now remove the minute from original datetime, & add the rounded minute to the resultant datetime value
       -- this will give you expected result
       , dateadd(minute 
                   , (round(datepart(minute, original_datetime) * 1.0 / 15 , 0) * 15.0)
                   , dateadd(minute, -datepart(minute, original_datetime), original_datetime)
                 ) as rec_datetime
      
      FROM (values('2015-11-24 19:06:00.000')
                 ,('2015-11-24 19:09:00.000')
               ,('2015-11-24 19:56:00.000')
               ,('2015-11-24 19:48:00.000')
           ) x(original_datetime)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-24
        • 1970-01-01
        • 2013-10-17
        • 1970-01-01
        • 2022-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多