2013-08-21 35 views
2

我有这样的SQL Server表:十大事件持续时间

TimeStamp (datetime)| Alarm (string) | Active (bool) 
01.08.2013 1:30:05 | Alarm 1    | false 
01.08.2013 1:29:54 | Alarm 2    | true 
01.08.2013 1:28:43 | Alarm 1    | true 
01.08.2013 1:27:21 | Alarm 3    | false 
01.08.2013 1:26:35 | Alarm 1    | false 
01.08.2013 1:25:34 | Alarm 1    | true 

我已经显示前10个报警事件:

SELECT TOP 10 Alarm, COUNT(Alarm) AS Occurrence 
FROM MyTable 
WHERE (Active = 'True') 
GROUP BY Alarm 
ORDER BY Occurrence DESC 

我现在需要前10个报警时间

目标是让每个警报的持续时间总和(从真到假)。

我真的被封锁在这,我想我需要迭代每行,并为每个满足的报警求和时间值。

但我不知道如何用SQL查询来做到这一点。任何帮助或方向将不胜感激。

预先感谢


@Roman PEKAR:SQL服务器2008

@戈登·利诺夫:预期输出=>顶部10报警持续时间(当警报为真))

time[min] | Alarm 

50 | Alarm 2 
34 | Alarm 3 
22 | Alarm 1 

... 
+0

你有什么版本的SQL Server? –

+2

请提供样本输出。目前还不清楚您希望结果是针对问题中的数据。 –

+0

如何计算报警2和报警3的时间,因为每个报警只发生一次(报警2 = 1真,报警3 = 1假)?另外,对于报警1,你需要2行还是只有1.我的意思是,你要计算总持续时间或两个持续时间,1:25:34到1:26:35,然后是1:28:43到1 :30:05? –

回答

1

你可以用cross apply找到之后的on

select top 10 active.Alarm 
,  active.TimeStamp as TimeOn 
,  active.TimeStamp as TimeOff 
,  datediff(second, active.TimeStamp, inactive.TimeStamp) as Duration 
from YourTable active 
cross apply 
     (
     select top 1 * 
     from YourTable inactive 
     where inactive.Active = 'false' 
       and inactive.Alarm = active.Alarm 
       and inactive.TimeStamp > active.TimeStamp 
     order by 
       inactive.TimeStamp 
     ) inactive 
where active.Active = 'true' 
order by 
     Duration desc 

See it working at SQL Fiddle.

+0

非常感谢您的回答,它可以帮助我很多! – Thierry

1

下面是另一种解决方案,其可以是更有效的。

;with a as 
(
    select a.Alarm 
    , a.Active 
    , a.[Timestamp] 
    , Sequence = dense_rank() over 
       (
        partition by a.Alarm, a.Active 
        order by a.[TimeStamp] 
       ) 
    from #YourTable a 
), 
b as 
(
    select a.Alarm 
    , Start = b.[Timestamp] 
    , Stop = a.[Timestamp] 
    from a 
    left outer join a b 
    on b.Alarm = a.Alarm 
    and b.Sequence = a.Sequence 
    and b.Active = 'true' 
    where a.Active = 'false' 
) 
select b.Alarm 
, DurationMinutes = sum(datediff(millisecond, b.Start, b.Stop)/1000.0/60.0) 
from b 
group by b.Alarm 
+0

可能更高效,但也要求更高的数据一致性。如果第一行是先前警报的结束(“关闭”条目),则查询将返回负值持续时间。 – Andomar

+0

@Andomar真的。您可以将'and b.Timestamp