Một phương pháp sử dụng lag()
:
select t.*
from (select t.*,
lag(status) over (partition by val, name order by date) as prev_status
from t
) t
where status = 'open' and
(prev_status is null or prev_status <> 'open');
Điều này có thể trả về nhiều hơn một kết quả cho một bài kiểm tra, nếu trạng thái có thể "trở lại" thành 'open'
. Bạn có thể sử dụng row_number()
nếu bạn không muốn hành vi này:
select t.*
from (select t.*,
row_number() over (partition by val, name, status order by date) as seqnum
from t
) t
where status = 'open' and seqnum = 1;
CHỈNH SỬA:
(đối với dữ liệu đã điều chỉnh)
Bạn chỉ có thể sử dụng kết hợp có điều kiện:
select val, name,
min(case when status = 'open' then status end) as o_gate,
min(case when status = 'open' then dt end) as o_dt,
max(case when status = 'close' then status end) as c_gate,
max(case when status = 'close' then dt end) as c_dt,
from t
group by val, name;
Tại đây là một db <> fiddle
Nếu bạn muốn tạo lại id
, bạn có thể sử dụng một biểu thức như:
row_number() over (order by min(dt)) as id