2014-04-10 5 views
0

Я сделал запрос:Найти разницу между часами

SELECT  
MemberId, 
     FirstName,LastName, 
     [DateOfChange]   
     ,(select title from StatusList where idStatus=[OldStatus]) as [OldStatus] 
     ,(select title from StatusList where idStatus=[NewStatus]) as [NewStatus] 
    FROM [statusLog] , Users where 
    statusLog.IdUser=Users.IdUser 

Этот запрос дает мне следующий результат:

enter image description here

У меня есть OLDSTATUS и NEWSTATUS и DateOfChange статуса в колонке.

Я просто хотел иметь разницу в часах изменения статуса.

т.е. от DateOfChange Для Старый Статус OnCall патрулировать я хочу найти разницу между двумя датами, как:

2014-04-04 16:13:33:000 and 2014-04-04 16:13:44:000 

Я пробовал:

SELECT  
MemberId, 
     FirstName,LastName, 
     [DateOfChange], 
     DATEDIFF(HOUR,select [DateOfChange] from statusLog,Users where idstatus=[OldStatus] 
     ,select [DateOfChange] from statusLog,Users where idstatus=[NewStatus])   
     ,(select title from StatusList where idStatus=[OldStatus]) as [OldStatus] 
     ,(select title from StatusList where idStatus=[NewStatus]) as [NewStatus] 
    FROM [statusLog] , Users where 
    statusLog.IdUser=Users.IdUser 

Но это оленья кожа работала.

две таблицы, которые я присоединившиеся являются:

Пользователи:

enter image description here

statusLog:

enter image description here

Пожалуйста, помогите мне.

Как я могу иметь разницу в часах, подобных этому в запросе выше?

Edit:

SELECT  
MemberId, 
     FirstName,LastName, 
     [DateOfChange]  , 

     (SELECT 

    DATEDIFF(HOUR, SL.DateOfChange, SLN.StatusTo) AS StatusDuration 
FROM 
    StatusLog SL 
    OUTER APPLY (
     SELECT TOP(1) 
      DateOfChange AS StatusTo 
     FROM 
      StatusLog SLT 
     WHERE 
      SL.IdUser = SLT.IdUser 
      AND SLT.DateOfChange > SL.DateOfChange 
     ORDER BY 
      SLT.DateOfChange ASC 
    ) SLN) Hourss 

     ,(select title from StatusList where idStatus=[OldStatus]) as [OldStatus] 
     ,(select title from StatusList where idStatus=[NewStatus]) as [NewStatus] 
    FROM [statusLog] , Users where 
    statusLog.IdUser=Users.IdUser 

Edit 2:

enter image description here

ответ

1

Вот SQL-запрос возвращения желаемого результата, просто используя саб выбрать:

SELECT [users].MemberId, 
    [users].FirstName, 
    [users].LastName, 
    thisLog.DateOfChange, 
    statusList1.title as OldStatus, 
    statuslist2.title as NewStatus, 
    (SELECT TOP 1 DATEDIFF(hour,lastLog.DateOfChange,thisLog.DateOfChange) 
    from [dbo].[statusLog] lastLog WHERE lastLog.DateOfChange<thisLog.DateOfChange 
    ORDER BY DateOfChange desc) AS HoursSinceLastChange 
    FROM [dbo].[statusLog] thisLog 
    INNER JOIN [users] ON [users].IdUser=thisLog.IdUSer 
    INNER JOIN StatusList statusList1 ON statusList1.idStatus=thisLog.OldStatus 
    INNER JOIN StatusList statusList2 on statusList2.idStatus=thisLog.Newstatus 
    order by DateOfChange desc 

Надеюсь, я все ваши колонки и имена таблиц правильно.

+0

его отображение неправильных значений –

+0

Я сделал редактирование 7 минут назад, добавив заказ в подборе select. Вы пробовали после смены? –

+0

Да, я сделал это и получил результат, как указано выше, в редакторе 2, но его неправильная разница в часах –

1

Начать с этим (вы должны присоединиться к пользователям и что вы хотите)

SELECT 
    SL.DateOfChange AS StatusFrom 
    , SLN.StatusTo AS 
    , DATEDIFF(HOUR, SL.DateOfChange, SLN.StatusTo) AS StatusDuration 
FROM 
    StatusLog SL 
    OUTER APPLY (
     SELECT TOP(1) 
      DateOfChange AS StatusTo 
     FROM 
      StatusLog SLT 
     WHERE 
      SL.IdUser = SLT.IdUser 
      AND SLT.DateOfChange > SL.DateOfChange 
     ORDER BY 
      SLT.DateOfChange ASC 
    ) SLN 
    INNER JOIN Users U 
     ON SL.IdUser = U.IdUser 
    INNER JOIN StatusList SLO -- Old status 
     ON SL.OldStatus = SLO.idStatus 
    INNER JOIN StatusList SLC -- Current status 
     ON SL.NewStatus = SLC.idStatus 

Оператор APPLY позволяет вам вызывать функцию табличной функции для каждой строки, возвращаемой внешним выражением таблицы запроса. Функция table-value действует как правый вход, а выражение внешней таблицы действует как левый вход. Правильный ввод оценивается для каждой строки с левого ввода, а полученные строки объединяются для окончательного вывода. Список столбцов, созданных оператором APPLY, представляет собой набор столбцов на левом входе, за которым следует список столбцов, возвращаемых правильным вводом. From MSDN: Using APPLY

В качестве примечания: Функция табличного значения может быть подзапросом тоже.

Я предлагаю вам использовать явный синтаксис соединения (INNER JOIN) вместо неявного (перечислить таблицы и использовать условие WHERE).

+0

Ваш запрос работает нормально, когда я запускаю его отдельно, но когда я пытаюсь разместить его в моем предыдущем запросе, тогда он дает мне ошибку ... subqury возвращает более одного столбца ... пока я размещаю отдельный столбец разницы из вашего запроса только ... плз увидеть редактировать часть –

+0

Просто добавьте INNER JOIN USers U ON SL.IdUser = U.IdUser INNER JOIN StatusList SLO - Старый статус ON SL.OldStatus = SLO.idStatus INNER JOIN StatusList SLC - Текущее состояние ON SL.NewStatus = SLC.idStatus в конец запроса. – Pred

+0

Также обратите внимание: если вы хотите узнать время между последним и текущим, просто измените направление заказа и настройте второе условие. (SLT.DateOfChange Pred

0

Когда я столкнулся с этой проблемой, я вставил ее в таблицу темпа. Это позволяет вам делать много классных вещей.

declare @tab TABLE([Date1] TIME, [DATE2] TIME) 

Insert @tab(SELECT DATE1 ,DATE2 FROM WHEREVER) 

SELECT (DATEDIFF(DATE1,DATE2) AS Difference FROM @tab 
Смежные вопросы