У вас есть два варианта:
select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
from (
select code, min(period) min_period, max(period) max_period,
max(min(period)) over (partition by code) max_min_period
from (
select code, period, sum(flag) over (partition by code order by period) grp
from (
select code, period,
case when add_months(period, -1)
= lag(period) over (partition by code order by period)
then 0 else 1 end flag
from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
group by code, grp)
where min_period = max_min_period
Пояснение:
- флаг строки, где период не равен предыдущему периоду плюс один месяц,
- создать столбец
grp
, который последовательно суммирует флаги,
- группировать данные, используя
code
и grp
, дополнительно находя максимальное начало периода,
- показывать только те строки, где
min_period
= max_min_period
Второй вариант - рекурсивный CTE, доступный в Oracle 11g и выше:
with
data(period, code) as (
select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
where mrdg_per_period between 201601 and 201812),
cte (period, code) as (
select to_char(period, 'yyyymm'), code from data
where (period, code) in (select max(period), code from data group by code)
union all
select to_char(data.period, 'yyyymm'), cte.code
from cte
join data on data.code = cte.code
and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
select code, min(period) min_period, max(period) max_period
from cte group by code
Пояснение:
- подзапрос
data
фильтрует только строки из 2016
- 2018
, дополнительно преобразовывая период в формат даты. Нам это нужно для работы функции add_months
.
cte
является рекурсивным. Якорь находит начальные строки с максимальным периодом для каждого кода. После union all
есть рекурсивный член, который ищет строку на месяц старше , чем текущий. Если он найдет его, то чистая строка, если нет - остановитесь.
- данные окончательного выбора групп. Обратите внимание, что период, который не был последовательным, был отклонен на
cte
.
Хотя рекурсивные запросы медленнее, чем традиционные, могут быть сценарии, когда второе решение лучше.
Вот демоверсия dbfiddle для обоих запросов. Удачи.