SQL Server: десятичная разница во времени - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь преобразовать десятичную разницу во времени, но всегда округлять, вызывая проблему.

declare @Accrued decimal(9,4) = 24.60
declare @Used decimal(9,4) = 23.5734
declare @Remaining decimal(9,2) = @Accrued -  @Used

declare @RoundAccrued decimal(9,2) = ceiling(@Accrued * 100) /  100
declare @RoundUsed decimal(9,2) =  ceiling(@Used * 100) /  100
declare @RoundRemaining decimal(9,2) =  ceiling(@Remaining * 100) /  100

declare @hrAcc int = @Accrued
select left(cast (@hrAcc as varchar), 4) + '.' + right('0' + cast((floor((@RoundAccrued * 60) % 60)) as varchar), 2) Accrued

declare @hrUsed int = @Used
select left(cast (@hrUsed as varchar), 4) + '.' + right('0' + cast((floor((@RoundUsed * 60) % 60)) as varchar), 2) Used
declare @hrRem int = @Remaining
select  left(cast (@hrRem as varchar), 4) + '.' + right('0' + cast((floor((@RoundRemaining * 60) % 60)) as varchar), 2) Remaining

Результаты

  • Начислено: 24,36
  • Использовано:23,34
  • Осталось: 1,01 (вместо 1,02)

Отлично работает на Accrued и Used, но что бы я ни делал, он все равно либо на одну минуту меньше, либо большечем в другое время.

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Все это происходит из-за использования округления, потолка и пола.

PLease see the details in the image below

Вы можете использовать что-то вроде ниже:

select convert(varchar(10), @hrAcc) + '.'+ right('0' + cast(cast((@Accrued-@hrAcc)*60 as int) as varchar),2)
select convert(varchar(10), @hrUsed) + '.'+ right('0' + cast(cast((@Used-@hrUsed)*60 as int) as varchar),2)
select cast((abs(cast(@hrAcc*60+cast((@Accrued-@hrAcc)*60 as int) as int) - cast(@hrUsed*60+cast((@Used-@hrUsed)*60 as int) as int)))/60 as varchar)
    +'.'
    + cast((abs(cast(@hrAcc*60+cast((@Accrued-@hrAcc)*60 as int) as int) - cast(@hrUsed*60+cast((@Used-@hrUsed)*60 as int) as int)))%60 as varchar)

--- Тест (использование округленных значений вместо необработанных)

 declare @Accrued decimal(9,4) = 0.5333--106.325--106.325--51.2568--49.9217--106.325--49.9217--24.60
    declare @Used decimal(9,4) = 0.0333--87.885--87.885--49.9217--51.2568--87.88--51.2568--23.5734
    declare @Remaining decimal(9,4) = @Accrued -  @Used
declare @hrAcc int = @Accrued
declare @hrUsed int = @Used
declare @hrRem int = @Remaining 

declare @RoundAccrued decimal(9,4) = ceiling(@Accrued * 100) /  100
declare @RoundUsed decimal(9,4) =  ceiling(@Used * 100) /  100
declare @RoundRemaining decimal(9,4) =  ceiling(@Remaining * 100) /  100

select convert(varchar(10), @hrAcc) + '.'+ right('0' + cast(cast((@RoundAccrued-@hrAcc)*60 as int) as varchar),2) Accrued
select convert(varchar(10), @hrUsed) + '.'+ right('0' + cast(cast((@RoundUsed-@hrUsed)*60 as int) as varchar),2) Used
select cast((abs(cast(@hrAcc*60+cast((@RoundAccrued-@hrAcc)*60 as int) as int) - cast(@hrUsed*60+cast((@RoundUsed-@hrUsed)*60 as int) as int)))/60 as varchar)
    +'.'
    + cast((abs(cast(@hrAcc*60+cast((@RoundAccrued-@hrAcc)*60 as int) as int) - cast(@hrUsed*60+cast((@RoundUsed-@hrUsed)*60 as int) as int)))%60 as varchar) Remaining
0 голосов
/ 27 сентября 2018

Должно быть достаточно использовать секунды.Поэтому попробуйте следующее:

select cast(dateadd(second, @Remaining*60*60, 0) as time)

Это дает результат как тип данных времени.Обратите внимание, что этот тип ограничен 24 часами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...