Hi team,
I have a table with intervals of numbers. However, my table have intervals that overlap and a number can be in more than one interval.
For example,
start_interval | end_interval
1 | 2
2 | 4
3 | 6
...
The number 2 can be in both intervals (1-2) and (2-4). The number 3 can also be in two intervals (2-4) and (3-6), and so on.
I need a query to identify the overlapped intervals.
For example:
Interval || Overlapped interval
start_interval | end_interval || start_interval | end_interval
1 | 2 || 2 | 4
2 | 4 || 3 | 6
...
Below you can find my query:
with t1 (start_int, end_int) as (select 1 start_int, 2 end_int from dual
union all
select start_int+1 start_int, end_int+2 end_int from t1 where start_int < 20),
t2 as (select t1.start_int start_int_1, t1.end_int end_int_1, tt.start_int start_int_2, tt.end_int end_int_2
from t1
cross join t1 tt
where t1.start_int <> tt.start_int
and t1.end_int <> tt.end_int
and (tt.start_int <= t1.end_int and tt.end_int >= t1.start_int))
select t2.start_int_1, t2.end_int_1,
t2.start_int_2, t2.end_int_2
from t2
order by 1,2,3,4
However, my query returns repeated groups. For example:
Interval || Overlapped interval
start_interval | end_interval || start_interval | end_interval
1 | 2 || 2 | 4
2 | 4 || 1 | 2
2 | 4 || 3 | 6
3 | 6 || 2 | 4
...
I understand why I am getting duplicated groups, but I don't know how to remove them.
Can you please help me?
Thanks.
To exclude those you've already considered, check that the start_int of one table is strictly less than that in the other:
with t1 (start_int, end_int) as (
select 1 start_int, 2 end_int from dual
union all
select start_int+1 start_int, end_int+2 end_int
from t1 where start_int < 4
), t2 as (
select t1.start_int start_int_1, t1.end_int end_int_1, tt.start_int start_int_2, tt.end_int end_int_2
from t1
cross join t1 tt
where t1.start_int <> tt.start_int
and t1.end_int <> tt.end_int
and (tt.start_int <= t1.end_int and tt.end_int >= t1.start_int)
and t1.start_int < tt.start_int
)
select t2.start_int_1, t2.end_int_1,
t2.start_int_2, t2.end_int_2
from t2
order by 1,2,3,4;
START_INT_1 END_INT_1 START_INT_2 END_INT_2
1 2 2 4
2 4 3 6
2 4 4 8
3 6 4 8