在SQL Server中将日期时间舍入为最接近的15分钟

时间:2015-11-26 11:57:39

标签: sql-server datetime rounding

我在使用舍入datetime的SQL Server中遇到问题。我在datetime列中获得了rec_datetime,但我希望将此datetime舍入到新列r_datetime中,对于整个列,该列必须四舍五入到最接近的15分钟rec_datetime

示例:

  • [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.......

3 个答案:

答案 0 :(得分:9)

Round-down,round-nearest&四舍五入到最近的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分钟被添加到偏移量中。

由于整数除法,需要在几秒钟内完成。

Round Up

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

答案 1 :(得分: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

答案 2 :(得分:0)

在这种情况下,您需要将分钟四舍五入到最接近的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)