Вы можете использовать LEAD
для вычисления разницы между упорядоченными строками в таблице B
. Любая строка, имеющая разницу (до следующей строки), которая превышает значение step
для этой последовательности, является пробелом.
Вот эта концепция, реализованная (ниже). Я добавил идентификатор последовательности «3», который не имеет значений в таблице B, чтобы проиллюстрировать, что он генерирует правильное первое значение.
with
a (id, cstart, cend, step) as
(select 1, 4000, 4032, 4 from dual union all
select 2, 3, 20000, 1 from dual union all
select 3, 100, 200, 3 from dual
),
b (id, cnumber) as
(select 1, 4000 from dual union all
select 1, 4004 from dual union all
select 1, 4012 from dual union all
select 2, 4003 from dual
),
work1 as (
select a.id,
b.cnumber cnumber,
lead(b.cnumber,1) over ( partition by b.id order by b.cnumber ) - b.cnumber diff,
a.step,
a.cstart,
a.cend
from a left join b on b.id = a.id )
select w1.id,
CASE WHEN min(w1.cnumber) is null THEN w1.cstart
WHEN min(w1.cnumber)+w1.step < w1.cend THEN min(w1.cnumber)+w1.step
ELSE null END next_cnumber
from work1 w1
where ( diff is null or diff > w1.step )
group by w1.id, w1.step, w1.cstart, w1.cend
order by w1.id
+----+--------------+
| ID | NEXT_CNUMBER |
+----+--------------+
| 1 | 4008 |
| 2 | 4004 |
| 3 | 100 |
+----+--------------+
Вы можете дополнительно улучшитьрезультаты исключаются строки в таблице B, которые невозможно для последовательности. Например, исключить строку для идентификатора # 1, скажем, со значением 4007.