Get list with start and end values from table of datetimes

后端 未结 7 1471
难免孤独
难免孤独 2020-12-17 23:01

Currently i have a table built up like this way

DeviceID      Timestamp            Value
----------------------------------------
Device1       1.1.2011 10:0         


        
7条回答
  •  伪装坚强ぢ
    2020-12-17 23:35

    I've played around with some datatypes and names (just because I can, and because timestamp is a reserved word), and can get your requested result using your sample data.

    Sample data:

    create table Measures (
        DeviceID int not null,
        Occurred datetime not null,
        Value int not null,
        constraint PK_Measures PRIMARY KEY (DeviceID,Occurred)
    )
    go
    insert into Measures (DeviceID,Occurred,Value)
    select 1,'2011-01-01T10:00:00',3 union all
    select 1,'2011-01-01T10:00:01',4 union all
    select 1,'2011-01-01T10:00:02',4 union all
    select 1,'2011-01-01T10:00:04',3 union all
    select 1,'2011-01-01T10:00:05',4 union all
    select 1,'2011-01-01T14:23:14',8 union all
    select 1,'2011-01-01T14:23:15',7 union all
    select 1,'2011-01-01T14:23:17',4 union all
    select 1,'2011-01-01T14:23:18',2
    

    and now the query:

    ;with StartPeriods as (
        select m1.DeviceID,m1.Occurred as Started
        from Measures m1 left join Measures m2 on m1.DeviceID = m2.DeviceID and m2.Occurred < m1.Occurred and DATEDIFF(second,m2.Occurred,m1.Occurred) < 6
        where m2.DeviceID is null
    ), ExtendPeriods as (
        select DeviceID,Started,Started as Ended from StartPeriods
        union all
        select
            ep.DeviceID,ep.Started,m2.Occurred
        from
            ExtendPeriods ep
                inner join
            Measures m2
                on
                    ep.DeviceID = m2.DeviceID and
                    ep.Ended < m2.Occurred and
                    DATEDIFF(SECOND,ep.Ended,m2.Occurred) < 6
    )
    select DeviceID,Started,MAX(Ended) from ExtendPeriods group by DeviceID,Started
    

    The StartPeriods Common Table Expression (CTE) finds those rows from the Measures table that don't have a previous row within 5 seconds of them. The ExtendPeriods CTE then recursively extends these periods by finding new rows from Measures that occur up to 5 seconds after the current end of the found period.

    We then find the rows where the end of the period was as far away from the start as possible.

提交回复
热议问题