приведение нечетного времени smallint к формату datetime - PullRequest
1 голос
/ 02 мая 2010

Я работаю с БД (SQL Server 2008), и у меня есть интересная проблема со временем, хранящимся в БД.

Администратор БД, который изначально его настраивал, был хитрым и сохранял запланированное время в виде строчек в 12-часовом формате - 6:00 утра было бы представлено как 600. Я выяснил, как разделить их на часы и минуты, например так:

select floor(time/100) as hr, right(time, 2) as min from table;

Я хочу сравнить это запланированное время с фактическим временем, которое хранится в правильном формате даты и времени. В идеале, я бы сделал это с двумя полями datetime и использовал бы между ними datediff (), но для этого потребовалось бы преобразовать время smallint в datetime, что я не могу понять.

У кого-нибудь есть предложения, как это сделать?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 02 мая 2010

Поскольку вы используете SQL Server 2008, вы можете воспользоваться новым типом данных Time. Чтобы преобразовать целое число в значение времени, мы должны предположить, что последние две цифры - минуты. Чтобы получить мельчайшую часть, разделите на 100, возьмите целочисленную часть и вычтите ее из начального значения. Таким образом, в случае 621 мы получаем:

621 - Floor(621/100)* 100
621 - Floor(6.21)*100
621 - 6*100
621 - 600 = 21 minutes

Для части часа мы можем просто взять целочисленное значение после деления на 100.

Create Table #Test( IntVal smallint not null )
Insert #Test Values( 621 )
Insert #Test Values( 2359 )
Insert #Test Values( 1200 )
Insert #Test Values( 1201 )
Insert #Test Values( 1159 )

Select Z.TimeVal, GetDate(), DateDiff(hh, Z.TimeVal, Cast(GetDate() As Time(0)))
From    (
        Select Cast(DateAdd(mi
                    , IntVal - Floor(IntVal/100)*100
                    , DateAdd(hh, Floor(IntVal/100), 0)
                    ) As Time(0)) As TimeVal
        From #Test
        ) As Z

Часть хитрости здесь заключается в использовании DateAdd(hh, Floor(IntVal/100), 0), который делает DateAdd против нулевого значения для datetime.

1 голос
/ 02 мая 2010

Можно придумать два способа сделать это. Первый - создать строку в формате HH:MM и привести ее к datetime. Второй - преобразовать формат smallint в float с количеством дней в качестве единицы. Количество дней является внутренним временным представлением, поэтому вы также можете привести его к datetime.

Пример кода:

declare @i smallint
set @i = 621

-- Cast to a string '6:21', then to a datetime
select cast(CAST(@i / 100 as varchar) + ':' + CAST(@i % 100 as varchar) 
    as datetime)

-- Convert to number of days, which is the interal datetime format
select cast((@i/100)/24.0 + (@i%100)/(24*60.0) as datetime)

P.S. Если вы делите целое число на другое целое число. результат - третье целое число: 100 / 24 = 4. Если вы разделите целое число на число с плавающей точкой, результатом будет число с плавающей точкой: 100 / 24.0 = 4.16666.

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