Вот один из способов сделать это, используя предложение match_recognize
(Oracle 12.1 и выше). Если я правильно понимаю, «пробел» существует, когда существует одна или несколько строк с кодом состояния «N» - и только в том случае, если перед такими строками предшествует строка «Y» для той же комбинации pk_1, pk_2, pk_3
. Таким образом, в ваших выборочных данных есть только один такой пробел. Вы не объяснили, что именно вы хотите показать (я предполагаю число, но вы не объяснили, как его вычислить). Я интерпретировал это как разницу между начальным значением «текущей» последовательности и конечным значением «предыдущей» последовательности.
with
yourtable (pk_1, pk_2, pk_3, sequence_no, status_code) as (
select 20200421, 'A', 1, 1, 'Y' from dual union all
select 20200421, 'A', 1, 2, 'Y' from dual union all
select 20200421, 'A', 1, 3, 'Y' from dual union all
select 20200421, 'A', 1, 4, 'N' from dual union all
select 20200421, 'A', 1, 5, 'Y' from dual union all
select 20200421, 'A', 1, 6, 'Y' from dual union all
select 20200421, 'A', 2, 7, 'Y' from dual union all
select 20200421, 'A', 2, 8, 'Y' from dual union all
select 20200421, 'B', 3, 9, 'Y' from dual union all
select 20200421, 'B', 3, 10, 'Y' from dual union all
select 20200421, 'B', 3, 11, 'Y' from dual union all
select 20200422, 'B', 3, 11, 'Y' from dual
)
select mr.*
, sequence_from - lag(sequence_to) over (partition by pk_1, pk_2, pk_3
order by sequence_from) as gap
from yourtable
match_recognize(
partition by pk_1, pk_2, pk_3
order by sequence_no
measures first(sequence_no) as sequence_from
, last (sequence_no) as sequence_to
pattern ( Y+ )
define Y as status_code = 'Y'
) mr
;
Вывод:
PK_1 PK_2 PK_3 SEQUENCE_FROM SEQUENCE_TO GAP
---------- ---- ---------- ------------- ----------- ----------
20200421 A 1 1 3
20200421 A 1 5 6 2
20200421 A 2 7 8
20200421 B 3 9 11
20200422 B 3 11 11