Get list with start and end values from table of datetimes

后端 未结 7 1517
难免孤独
难免孤独 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:29

    The basic idea for the below solution has been borrowed from this answer.

    WITH data (DeviceID, Timestamp, Value) AS (
      SELECT 'Device1', CAST('1.1.2011 10:00:00' AS datetime), 3 UNION ALL
      SELECT 'Device1',      '1.1.2011 10:00:01',              4 UNION ALL
      SELECT 'Device1',      '1.1.2011 10:00:02',              4 UNION ALL
      SELECT 'Device1',      '1.1.2011 10:00:04',              3 UNION ALL
      SELECT 'Device1',      '1.1.2011 10:00:05',              4 UNION ALL
      SELECT 'Device1',      '1.1.2011 14:23:14',              8 UNION ALL
      SELECT 'Device1',      '1.1.2011 14:23:15',              7 UNION ALL
      SELECT 'Device1',      '1.1.2011 14:23:17',              4 UNION ALL
      SELECT 'Device1',      '1.1.2011 14:23:18',              2
    ),
    ranked AS (
      SELECT
        *,
        rn = ROW_NUMBER() OVER (PARTITION BY DeviceID ORDER BY Timestamp)
      FROM data
    ),
    starts AS (
      SELECT
        r1.DeviceID,
        r1.Timestamp,
        rank = ROW_NUMBER() OVER (PARTITION BY r1.DeviceID ORDER BY r1.Timestamp)
      FROM ranked r1
        LEFT JOIN ranked r2 ON r1.DeviceID = r2.DeviceID
          AND r1.rn = r2.rn + 1
          AND r1.Timestamp <= DATEADD(second, 5, r2.Timestamp)
      WHERE r2.DeviceID IS NULL
    ),
    ends AS (
      SELECT
        r1.DeviceID,
        r1.Timestamp,
        rank = ROW_NUMBER() OVER (PARTITION BY r1.DeviceID ORDER BY r1.Timestamp)
      FROM ranked r1
        LEFT JOIN ranked r2 ON r1.DeviceID = r2.DeviceID
          AND r1.rn = r2.rn - 1
          AND r1.Timestamp >= DATEADD(second, -5, r2.Timestamp)
      WHERE r2.DeviceID IS NULL
    )
    SELECT
      s.DeviceID,
      Started = s.Timestamp,
      Ended = e.Timestamp
    FROM starts s
      INNER JOIN ends e ON s.DeviceID = e.DeviceID AND s.rank = e.rank
    

提交回复
热议问题