十大活动持续时间

时间:2013-08-21 13:34:41

标签: sql sql-server sql-server-2008 select

我有一个像这样的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

我现在需要前十名警报持续时间

目标是为每个警报设置持续时间总和(从true到false)。

我真的被封锁了,我想我需要为每个遇到的警报迭代每一行和时间值。

但我不知道如何使用SQL查询。任何帮助或指示都将不胜感激。

提前致谢


@Roman Pekar:SQL server 2008

@ Gordon Linoff:输出预期=>前10个警报持续时间(当警报为真时))

time[min] | Alarm

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

...

2 个答案:

答案 0 :(得分:1)

您可以使用cross apply查找off之后的第一个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.

答案 1 :(得分: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