求每个连续的相同状态的片段的开始及结束边界
postgresql:
with a as (
select 0 hour_index,'启' state
union all select 1 hour_index,'停' state
union all select 2 hour_index,'停' state
union all select 3 hour_index,'启' state
union all select 4 hour_index,'启' state
union all select 5 hour_index,'启' state
union all select 6 hour_index,'停' state
union all select 7 hour_index,'启' state
union all select 8 hour_index,'停' state
union all select 9 hour_index,'停' state
union all select 10 hour_index,'启' state
union all select 11 hour_index,'启' state
),b as (
SELECT hour_index,state,lag(state) over(order by hour_index) lag_state
from a
),c as (
select hour_index,state, lag_state, case when state=lag_state then 0 else 1 end is_first
from b
),d as (
select hour_index,state, lag_state,is_first
from c
)
select *,sum(is_first) over( order by hour_index) group_id
from d
order by 1
结果:
hour_index | state | lag_state | is_first | group_id |
---|---|---|---|---|
0 | 启 | null | 1 | 1 |
1 | 停 | 启 | 1 | 2 |
2 | 停 | 停 | 0 | 2 |
3 | 启 | 停 | 1 | 3 |
4 | 启 | 启 | 0 | 3 |
5 | 启 | 启 | 0 | 3 |
6 | 停 | 启 | 1 | 4 |
7 | 启 | 停 | 1 | 5 |
8 | 停 | 启 | 1 | 6 |
9 | 停 | 停 | 0 | 6 |
10 | 启 | 停 | 1 | 7 |
11 | 启 | 启 | 0 | 7 |
这样就可以通过分组求 MIN()& MAX()得到起止位置了。