lag()
- самый простой метод:
select t.*
from (select t.*,
lag(status) over (partition by id, (case when inoutdate is null then 1 else 2 end)
order by inoutdate
) as prev_status
from t
) t
where prev_status is null or prev_status <> status;
Вы можете рассматривать это как проблему групп и островов, идентифицируя острова с помощью row_number()
.Логика более сложная:
select t.*
from (select t.*,
row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end), status, (seqnum - seqnum_s)
order by inoutdate
) as seqnum_g
from (select t.*,
row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end) order by inoutdate) as seqnum,
row_number() over (partition by id, (case when inoutdate is null then 1 else 2 end), status order by inoutdate) as seqnum_s
from t
) t
) t
where seqnum_g = 1;