with tmp as
(select date '2017-1-2' as begin_date, date '2017-1-8' as end_date
from dual
union all
select date '2017-1-2' as begin_date, date '2017-1-4' as end_date
from dual
union all
select date '2017-1-15' as begin_date, date '2017-1-20' as end_date
from dual
union all
select date '2017-1-18' as begin_date, date '2017-1-28' as end_date
from dual
union all
select date '2017-1-19' as begin_date, date '2017-1-20' as end_date
from dual)
select sum (max(end_date) - min(begin_date)) as total_num
from (select begin_date,
end_date,
max(rn) over(order by begin_date, end_date) as rn
from (select begin_date,
end_date,
case
when begin_date <= max(end_date)
over(order by begin_date,
end_date rows between unbounded
preceding and 1 preceding) then
0
else
row_number() over(order by begin_date, end_date)
end as rn
from tmp))
group by rn;