2015-01-10 8 views
1

У меня есть 2 столбца в моей таблице на сервере sql - [Время появления (NT)] и [Время зазора (NT)], имеющее формат yyyy-mm-dd hh: mm: ss и третий столбец [Продолжительность вылета] с формат hh: mm: ssКак рассчитать разницу между двумя полями datetime (yyyy-mm-dd hh: mm: ss) в формате времени (hh: mm: ss) в sql-сервере?

[Идентификатор] | [Время появления (NT)] | [Время простоя (NT)] | [Продолжительность простоя]

4 | 2014-12-28 15: 06: 33.000 | 2014-12-28 15: 18: 18.000 | 00: 11: 45,000

длительность перелива рассчитывается как разность [Вхождение времени (NT)] и [Время очистки (NT)] В настоящее время мой код, чтобы сделать это следующим образом:

select distinct a.[Identifier] 
    ,a.[Occurrence Time(NT)] 
    ,a.[Clearance Time(NT)] 
    ,cast((cast(a.[Clearance Time(NT)] as datetime) - cast(a.[Occurrence Time(NT)]as datetime)) as time) 
    as [Outage Duration] 
    from final_report_2 a 

Листинг просто отказоустойчив, поскольку оба столбца уже имеют дату и время. Этот код работает во всех случаях, когда [Время появления (NT)] и [Время зазора (NT)] выпадают в тот же день, то есть отключение в течение 24 часов

Например, в приведенном выше номере. 4 оба имеют 28-е число в день, и, следовательно, исчисление рассчитывается правильно.

Но продолжительность простоя ошибочно рассчитана в случае разных дней.

2678 | 2014-12-28 12: 50: 04.000 | 2014-12-31 23: 59: 59.000 | 11: 09: 55.000

В строке 2678 время должно быть 83:09:55 вместо 11:09:55.

Так что мне нужно также учитывать разницу между днями, а затем вычислить продолжительность [Outage duration] в формате hh: mm: ss.

Один из возможных способов сделать это заключается в следующем:

(23:59:59 - 12:50:04) + 00:00:01 + ((31-28-1) * 24): 00: 00 + 23:59:59

где первая часть вычисляет время первого дня, затем вторая часть вычисляет значение no. целых дней между [Время появления (NT)] и [Время зазора (NT)] и умножает его на 24, а заключительная часть представляет время последнего дня.

Как я могу реализовать выше в sql-сервере? Можно ли использовать функции DATEPART или DATEADD?

ответ

1

необходимо использовать datediff функция.

Сначала найдите difference в seconds между двумя датами.

select Datediff(SECOND, [Clearance Time(NT)], [Occurrence Time(NT)]) 

Теперь конвертировать seconds в hh:mm:ss, используя этот код.

DECLARE @TimeinSecond INT 
SET @TimeinSecond = 86399 -- Change the seconds 
SELECT RIGHT('0' + CAST(@TimeinSecond/3600 AS VARCHAR),2) + ':' + 
RIGHT('0' + CAST((@TimeinSecond/60) % 60 AS VARCHAR),2) + ':' + 
RIGHT('0' + CAST(@TimeinSecond % 60 AS VARCHAR),2) 

Измените ваш запрос примерно так.

SELECT DISTINCT a.[Identifier], 
       a.[Occurrence Time(NT)], 
       a.[Clearance Time(NT)], 
       RIGHT('0' + Cast(Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)])/3600 AS VARCHAR), 2) 
       + ':' 
       + RIGHT('0' + Cast((Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)])/60) % 60 AS VARCHAR), 2) 
       + ':' 
       + RIGHT('0' + Cast(Datediff(SECOND, [Clearance Time(NT)],[Occurrence Time(NT)]) % 60 AS VARCHAR), 2) [Outage Duration] 
FROM final_report_2 a 

Ссылка: преобразование seconds в hh:mm:ss перешедших из этого link

0

Хороший старый SQL DATEDIFF. Вот функция продолжительности, которую я использую. Все завершено в UDF.

CREATE FUNCTION fDuration(@DtStart DATETIME, @DtEnd DATETIME) 
RETURNS VARCHAR(10) 
AS 
BEGIN 
    RETURN (
SELECT 
CONVERT(VARCHAR(10), t.Hours) + ':' + 
RIGHT('00' + CONVERT(VARCHAR(10), t.Minutes), 2) + ':' + 
RIGHT('00' + CONVERT(VARCHAR(10), t.Seconds - (t.Hours * 60 * 60) - (t.Minutes) * 60), 2) as Value 
FROM (
    SELECT 
    t.Hours, 
    ABS(t.Seconds/60 - (t.Hours * 60)) as Minutes, 
    t.Seconds 
    FROM (
     SELECT 
      DATEDIFF(SECOND, @DtStart, @DtEnd) as Seconds, 
      DATEDIFF(SECOND, @DtStart, @DtEnd)/60/60 AS Hours) t 
    ) t) 
END 

ИСПОЛЬЗОВАНИЕ:

SELECT dbo.fDuration('2014-12-28 12:50:04.000', '2014-12-31 23:59:59.000') 

ВОЗВРАТ:

83:09:55 

В вашем случае, вы можете изменить ваш запрос, как этого

SELECT DISTINCT a.[Identifier], 
       a.[Occurrence Time(NT)], 
       a.[Clearance Time(NT)], 
       dbo.fDuration(a.[Occurrence Time(NT)], a.[Clearance Time(NT)]) as [Outage Duration] 
FROM final_report_2 a 

Или даже добавить [перелив Длительность] как вычисленное поле в final_report_2 с формой ULA

dbo.fDuration([Occurrence Time(NT)],[Clearance Time(NT)]) 

Тогда это становится просто выберите ...

SELECT DISTINCT a.[Identifier], 
       a.[Occurrence Time(NT)], 
       a.[Clearance Time(NT)], 
       a.[Outage Duration] 
FROM final_report_2 a 

Примечание Часы не с префиксом '0'. Это позволяет отрицательную длительность.

Надеюсь, что поможет