2015-07-09 4 views
1

Im пытается вычислить время простоя для обслуживания из данных, присутствующих в таблице. (База данных SQL)расчет времени простоя на основе значений состояния

таблица будет содержать следующие данные:

service  Status  RecordedTime 
    ID   ID 

    1    2  2015-07-08 12:02:25.257 
    1    3  2015-07-08 12:07:25.257 
    1    0  2015-07-08 12:12:25.257 
    1    4  2015-07-08 12:17:25.257 
    1    3  2015-07-08 12:22:25.257 
    2    0  2015-07-08 12:27:25.257 
    2    2  2015-07-08 12:32:25.257 
    2    4  2015-07-08 12:37:25.257 
    1    0  2015-07-08 12:42:25.257 
    1    3  2015-07-08 12:47:25.257 
    2    0  2015-07-08 12:52:25.257 
    2    1  2015-07-08 12:57:25.257 
    2    2  2015-07-08 13:02:25.257 
    2    3  2015-07-08 13:07:25.257 

несколько услуг существуют, и их статус отслеживается, где 0,2 => вниз, 1,3,4 => до

мне нужно рассчитать время простоя конкретной услуги в течение определенного дня/месяца/года

например: на основе вышеприведенного столового сервиза «1» имеют следующие данные:

service Status  RecordedTime 
    ID   ID 
    1   0  2015-07-08 12:12:25.257 
    1   4  2015-07-08 12:17:25.257 
    1   0  2015-07-08 12:42:25.257 
    1   3  2015-07-08 12:47:25.257 

поэтому результат для 1day будет

Date   Service  downtime 
      ID 
    2015-07-08  1   10mins 
    2015-07-08  2   1 hr 
    ... 
    2015-07-09  2   10mins 
    2015-07-09  1   1 hr 

Любые идеи о том, как запрос может быть вместе для достижения этой цели?

У меня есть следующий запрос, который делает их общую

select SIPTrunkID,0 as TrunkStatus,RecordTimeUtc 
from VoipGatewaySIPTrunkStats 
where ServiceProviderSIPTrunkStatus in (0,2)  
AND RecordTimeUtc BETWEEN (GetUTCDate() -1) AND GetUTCDate() 
AND SIPTrunkId = 1 

union 

(select SIPTrunkID,1 as TrunkStatus,RecordTimeUtc 
from VoipGatewaySIPTrunkStats 
where ServiceProviderSIPTrunkStatus not in (0,2) 
AND RecordTimeUtc BETWEEN (GetUTCDate() -1) AND GetUTCDate() AND SIPTrunkId = 1) 
order by RecordTimeUtc 

это я сделал это для одного ствола, и все же, чтобы получить значение времени простоя После этого он должен быть настроен и далее для все ствола каждого день

+2

Для чего это для этого? – OldProgrammer

+0

База данных - это база данных SQL – user1696218

+0

Я знаю, но какой продукт - Oracle, MS Sqlserver, ??? – OldProgrammer

ответ

0

Попробуйте этот запрос, он использует cross apply для доступа к следующему событию безотказной работы для каждого события времени простоя (за исключением последовательных событий времени простоя, где он подсчитывается с самого раннего времени) и вычисляет разницу.

select 
    date, 
    serviceid, 
    sum(datediff(minute, starttime, endtime)) downtime 
from (
    select 
     cast(t1.recordedtime as date) as date, 
     t1.serviceid, 
     min(t1.recordedtime) starttime, 
     ca.recordedtime endtime 
    from your_table t1 
    cross apply (
     select top 1 recordedtime 
     from your_table 
     where serviceid = t1.serviceid 
     and recordedtime > t1.recordedtime 
     and statusid in (1,3,4) 
     order by recordedtime 
    ) ca 
    where t1.statusid in (0,2) 
    group by cast(t1.recordedtime as date), t1.serviceid, ca.RecordedTime 
) a 
group by date, serviceId; 

С вашими данными выборки результат будет:

date  serviceid downtime 
2015-07-08 1   15 
2015-07-08 2   20 

который я считаю правильным, даже если она не совпадает с результатом выборки (но это, кажется, не имеют никакого отношения к фактические данные).

Sample SQL Fiddle

+0

это сработало спасибо :) – user1696218

0

Используйте LEAD, чтобы увидеть следующую запись. Вот правильный запрос на последних (благодаря полезные комментарии JPW в):

select 
    thedate, 
    serviceid, 
    sum(datediff(minute, starttime, endtime)) 
from 
(
    select 
    convert(date, recordedtime) as thedate, 
    serviceid, 
    statusid, 
    recordedtime as starttime, 
    lead(recordedtime) over (partition by serviceid order by recordedtime) as endtime 
    from your_table 
) start_and_end 
where statusid in (0,2) 
group by thedate, serviceid; 

В случае услуга по сравнению с скажем 23:55 один день до 0:05 другого, то время будет назначен день начала ,

+0

Это вызывает ошибку: _Windowed функции не могут использоваться в контексте другой оконной функции или aggregate._, поэтому вам придется вычислять diff в производной таблице и перемещать агрегат во внешний запрос. Однако есть еще одна проблема: события с отключением времени могут сопровождаться другими событиями времени простоя, но вывод будет возвращать следующее независимо от состояния, которое делает вычисление недействительным. Мне нравится идея использования свинца. – jpw

+0

@jpw: Спасибо, я не знал об этом ограничении и отредактировал свой ответ. Что касается последовательных записей о простоях: это не проблема; они складываются (от простоя 1 до простоя 2 плюс от простоя 2 до времени безотказной работы). –

+0

С вашим запросом на обновление время простоя доходит до 40 для serviceid 1 и 35 для serviceid 2. Возможно, это правильно, но, глядя на исходные данные, это кажется слишком высоким. Я мог бы неправильно истолковать этот вопрос. – jpw