我在使用舍入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.......
答案 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)