根据状态值

时间:2015-07-09 12:42:46

标签: sql sql-server

我试图根据表中的数据计算服务的停机时间。 (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

所以1天的结果将是

    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 个答案:

答案 0 :(得分: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停止,则时间将被指定为开始日。

答案 1 :(得分:0)

尝试此查询,它使用交叉应用来访问每个停机事件的下一个正常运行时间事件(连续停机事件除外,它从最早开始计算),并计算差异。

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