我正在计算两个小时间的小时数。客户希望将小时数四舍五入到最近的半小时。我的计算是:
hours = datediff(mi,ActualStart,ActualEnd)/60.0
这给了我一个漂浮物,我不能绕过时间四舍五入的方式。我知道如何围绕开始和结束时间,但宁愿将舍入应用于总小时数。
我正在使用SQL Server 2012
答案 0 :(得分:3)
DATEADD( minute, ( DATEDIFF( minute, 0, dateTimeX ) / 30 ) * 30, 0 ) AS dateTimeRoundDown,
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute, 30 / 2, dateTimeX ) ) / 30 ) * 30, 0 ) AS dateTimeRoundNearest,
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute, 30 , dateTimeX ) ) / 30 ) * 30, 0 ) AS dateTimeRoundUp
有关详细信息,请参阅this SO question & answer
单元测试
DECLARE @start DATETIME = '2017-04-20 21:00:00'
DECLARE @end DATETIME = '2017-04-20 23: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 ) / 30 ) * 30, 0 ) AS dateTimeRoundDown,
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute, 30 / 2, dateTimeX ) ) / 30 ) * 30, 0 ) AS dateTimeRoundNearest,
DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute, 30 , dateTimeX ) ) / 30 ) * 30, 0 ) AS dateTimeRoundUp
FROM CTE_dateTimes
OPTION ( MAXRECURSION 200 )
答案 1 :(得分:0)
这是你可以实现目标的一种方式,这应该足以让你开始解决问题:
declare @t table(s datetime, e datetime);
insert into @t values
('20170125 01:00:00','20170125 01:10:00'),('20170125 01:00:00','20170125 01:15:00'),('20170125 01:00:00','20170125 01:25:00'),('20170125 01:00:00','20170125 01:40:00'),('20170125 01:00:00','20170125 01:55:00'),('20170125 01:00:00','20170125 02:05:00'),('20170125 01:00:00','20170125 02:55:00'),('20170125 01:00:00','20170125 04:14:00'),('20170125 01:00:00','20170125 22:05:00');
select datediff(mi,s,e) as MinutesDiff
,datediff(mi,s,e) / 60 as HoursDiff
,datediff(mi,s,e) % 60 as MinutesRemain
-- Take the Minutes Remaining after all the full hours are removed,
-- and integer divide by 15 to get the number of full quarter hours
-- and then round to the nearest number of minutes to add on.
,case round(datediff(mi,s,e) % 60 / 15,0)
when 0 then 0
when 1 then 30
when 2 then 30
when 3 then 60
end as MinutesRounded
from @t;
输出:
+-------------+-----------+---------------+----------------+
| MinutesDiff | HoursDiff | MinutesRemain | MinutesRounded |
+-------------+-----------+---------------+----------------+
| 10 | 0 | 10 | 0 |
| 15 | 0 | 15 | 30 |
| 25 | 0 | 25 | 30 |
| 40 | 0 | 40 | 30 |
| 55 | 0 | 55 | 60 |
| 65 | 1 | 5 | 0 |
| 115 | 1 | 55 | 60 |
| 194 | 3 | 14 | 0 |
| 1265 | 21 | 5 | 0 |
+-------------+-----------+---------------+----------------+
答案 2 :(得分:0)
试试这个:
round( 48 * ( cast(ActualEnd as float)-cast(ActualStart as float) ),0) /2.0 as HoursRoundedToHalfHour,
将日期时间值转换为float会显示自特定日期以来的天数。
从另一个中减去一个给出两个日期时间之间的天数。
乘以48得到半小时的间隔数。
调用Round(x,0)将其舍入为最接近的整数。
除以2.0会将其转换为小时数。
示例:
create table Times ( ActualStart smalldatetime, ActualEnd smalldatetime )
insert into Times values
('20170125 01:00:00','20170125 01:10:00'),('20170125 01:00:00','20170125 01:15:00'),('20170125 01:00:00','20170125 01:25:00'),('20170125 01:00:00','20170125 01:40:00'),('20170125 01:00:00','20170125 01:55:00'),('20170125 01:00:00','20170125 02:05:00'),('20170125 01:00:00','20170125 02:55:00'),('20170125 01:00:00','20170125 04:14:00'),('20170125 01:00:00','20170125 22:05:00');
select
ActualStart,ActualEnd,
datediff(mi,ActualStart,ActualEnd) as [Minutes],
datediff(mi,ActualStart,ActualEnd)/60 as [Hr],
datediff(mi,ActualStart,ActualEnd)%60 as [Min],
round( 48 * ( cast(ActualEnd as float)-cast(ActualStart as float) ),0) /2.0 as [HoursRoundedToHalfHour]
from Times
ActualStart ActualEnd Minutes Hr Min HoursRoundedToHalfHour
----------------------- ----------------------- ----------- ----------- ----------- ----------------------
2017-01-25 01:00:00 2017-01-25 01:10:00 10 0 10 0
2017-01-25 01:00:00 2017-01-25 01:15:00 15 0 15 0.5
2017-01-25 01:00:00 2017-01-25 01:25:00 25 0 25 0.5
2017-01-25 01:00:00 2017-01-25 01:40:00 40 0 40 0.5
2017-01-25 01:00:00 2017-01-25 01:55:00 55 0 55 1
2017-01-25 01:00:00 2017-01-25 02:05:00 65 1 5 1
2017-01-25 01:00:00 2017-01-25 02:55:00 115 1 55 2
2017-01-25 01:00:00 2017-01-25 04:14:00 194 3 14 3
2017-01-25 01:00:00 2017-01-25 22:05:00 1265 21 5 21