SQL Server:根据列的连续值获取持续时间

时间:2016-01-11 12:43:12

标签: sql-server sql-server-2008-r2 group-by data-partitioning

我有一张像这样的表

ID           VehicleID             Time               EngineStatus
--          ----------      ------------------     ----------------
0              0001          1/11/2016 00:00              off
0              0002          1/11/2016 00:10              off
0              0003          1/11/2016 00:10              off
0              0001          1/11/2016 00:10              ON
0              0001          1/11/2016 00:11              ON
0              0003          1/11/2016 00:20              off
0              0002          1/11/2016 00:15              off
0              0001          1/11/2016 00:11              off
0              0001          1/11/2016 00:12              off
0              0001          1/11/2016 00:20              ON
0              0001          1/11/2016 00:25              ON

我想获得每辆车的EngineStatus及其持续时间。 我需要一个像这样的结果的查询

     Start              End                 Status        VehileID
---------------    --------------          --------      ----------
1/11/2016 00:00    1/11/2016 00:10           OFF            0001
1/11/2016 00:10    1/11/2016 00:11           ON             0001
1/11/2016 00:11    1/11/2016 00:12           Off            0001
1/11/2016 00:20    1/11/2016 00:25           ON             0001

1/11/2016 00:10    1/11/2016 00:15           OFF            0002

1/11/2016 00:10    1/11/2016 00:20           OFF            0003

我想我不得不根据列的连续值对数据进行分组,然后从每个组中获取第一行和最后一行。

2 个答案:

答案 0 :(得分:0)

这样的事情应该有效:

SELECT MIN([Time]) AS [Start], MAX([Time]) AS [End],
       EngineStatus, VehicleID
FROM (
  SELECT VehicleID, [Time], EngineStatus,
         ROW_NUMBER() OVER (PARTITION BY VehicleID ORDER BY [Time]) -
         ROW_NUMBER() OVER (PARTITION BY VehicleID, EngineStatus
                            ORDER BY [Time]) AS grp
  FROM mytable ) AS t
GROUP BY VehicleID, EngineStatus, grp

grp标识具有相同VehicleID, EngineStatus值的连续记录的片段。

答案 1 :(得分:0)

尝试;

;with data_tbl as (
    select 
        [VehicleID], 
        [Time], 
        [EngineStatus],
        dense_rank() over(partition by [VehicleID] order by [VehicleID], [Time]) rnk
    from tbl    
)
select
    t1.[Time] Start,
    t2.[Time] End,
    t1.[EngineStatus] Status,
    t1.[VehicleID] VehileID   
from data_tbl t1
join data_tbl t2 
on t1.[VehicleID] = t2.VehicleID 
and t1.rnk = t2.rnk - 1
and t1.[EngineStatus] = t2.[EngineStatus]
order by t1.[VehicleID], t1.[Time]