四舍五入到最接近的 15 分钟间隔

Round to nearest 15 minute interval

我已经看到这个问题被询问并回答了存储为日期的时间,但我将小时和分钟的持续时间存储为 numeric(4,2)。例如2.12,就是2小时12分钟。我需要将其四舍五入到最接近的 15 分钟间隔,这样做 (CONVERT([numeric](4,2),round(2.12/(25),(2))*(25))) 不起作用,因为它以 10 为基数并且四舍五入时间不正确。非常感谢任何帮助,谢谢。

编辑:我从示例中寻找的结果是 2.25

对于我的用例,持续时间需要以季度表示,

15 分钟 = .25

30 分钟 = .50

45 分钟 = .75

您不能对持续时间进行任何计算,因为它不是以 10 为基数,将其转换为以 10 为基数可能会导致精度丢失(例如 2 小时 1 分钟,您的格式为 2.01,转换为 2.01666666 ...)

最好将其转换为总分钟数,然后四舍五入并转换回您的格式


declare @duration numeric(4,2) = 2.12;

with 
cte1 as
(
    select  tot_mins = (floor(@duration) * 60) 
                     + (@duration * 100) % 100
),
cte2 as
(
    select  *, tot_mins_rounded = round(tot_mins / 15.0, 0) * 15
    from    cte1
)
select  *,
        convert_back_to_your_format = floor(tot_mins_rounded / 60) 
                                    + (tot_mins_rounded % 60) / 100.0
from    cte2

结果:

tot_mins tot_mins_rounded convert_back_to_your_format
132.00 135.000000 2.15000000000

理想情况下,您不会将持续时间存储为小数 - 如果总是少于 24 小时,则应存储为 time,如果可能多天,则应存储为 datetime2

通过以可接受的时间格式转换为字符串来转换为时间。然后使用找到的您最喜欢的解决方案 here.

select
  -- Original Value
   D.[Value]
   -- As Time
   , T.[Time]
   -- As Time Rounded
   , RT.[Time]
   -- As decimal
   , convert(decimal(9,2),datepart(hour,RT.[Time]) + datepart(minute,RT.[Time]) / 60.0)
from (
  -- Test Values
  values (2.12), (2.02), (0.12)
) D ([Value])
cross apply (
  -- Convert to time datatype
  values (convert(time(0), convert(varchar(8),convert(int, D.[Value])) + ':' + substring(convert(varchar(8),D.[Value] - convert(int, D.[Value])),3,8)))
) T ([Time])
cross apply (
  -- Round using your favourite method
  values (convert(time(0), dateadd(minute, round(datediff(minute, 0, T.[Time]) / 15.0, 0) * 15, 0)))
) RT ([Time]);

还有一个选择

declare @YourTable table (duration numeric(4,2))
Insert Into @YourTable values
 ( 2.12 )
,( 1.30 )
,( 1.55 )

Select  Duration 
       ,NewValue = floor(duration) + ceiling(((duration % 1) * 100 / 60 ) * 4) / 4
 From  @YourTable

结果

Duration    NewValue
2.12        2.250000
1.30        1.500000
1.55        2.000000