Я думаю, что вы можете использовать аналитическую функцию LEAD, чтобы получить дату начала следующего цикла, а затем сравнить ее с датой окончания периода:
create table contracts (
Customer_ID number,
Contract_Id number,
Start_Date date,
End_Date date
);
-- with gap
insert into contracts values (1, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (1, 21, to_date('02/06/2018','MM/DD/YYYY'), to_date('03/01/2018','MM/DD/YYYY'));
-- no gap (next start_date = end_date+1)
insert into contracts values (2, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (2, 21, to_date('02/02/2018','MM/DD/YYYY'), to_date('03/01/2018','MM/DD/YYYY'));
-- with gap. no end date
insert into contracts values (3, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (3, 21, to_date('02/06/2018','MM/DD/YYYY'), null);
-- no gap, no end date
insert into contracts values (4, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (4, 21, to_date('02/02/2018','MM/DD/YYYY'), null);
-- one period
insert into contracts values (5, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
-- one period, no end date
insert into contracts values (6, 21, to_date('01/01/2018','MM/DD/YYYY') , null);
commit;
select customer_id, contract_id, start_date, end_date, next_start_date, (next_start_date-end_date) as gap
from (
select customer_id, contract_id, start_date, end_date,
lead(start_date, 1, end_date+1) over (partition by customer_id, contract_id order by start_date) next_start_date
from contracts
)
where next_start_date != end_date + 1;
CUSTOMER_ID CONTRACT_ID START_DAT END_DATE NEXT_STAR GAP
----------- ----------- --------- --------- --------- ----------
1 21 01-JAN-18 01-FEB-18 06-FEB-18 5
3 21 01-JAN-18 01-FEB-18 06-FEB-18 5