아래와같이 시작숫자와 종료숫자가 있는데요.
각 행들이 서로 종속적으로 start1 와 end1 숫자 범위내에 포함되어있는 데이타를 추출하는 쿼리가 필요합니다.
예를들면 start1 는 start1 와 end1 숫자 범위내에 포함되어있어야하고요,
또는 end1 도 start1 와 end1 범위내에 포함되어있으면 출력입니다.
예상결과는 맨밑에 있습니다.
쿼리를 어떻게 변형해야 할까요?
with w_ip as
(
select '010' start1, '200' end1 from dual
union all select '011' start1, '015' end1 from dual
union all select '003' start1, '050' end1 from dual
union all select '080' start1, '255' end1 from dual
union all select '201' start1, '255' end1 from dual
union all select '001' start1, '002' end1 from dual
)
select *
from w_ip
-- 결과
start1 end1
----------------------------
'010' '200'
'011' '015'
'003' '050'
'080' '255'
전체 6개의 행중에서 4개만 출력된 이유는 서로 간의 시작숫자 및 종료숫자를 보면
서로 종속적으로 해당범위내에 포함이 되어잇습니다.
'010' '200' ==> 종료숫자인 200 이 '080' start1, '255' 사이에 포함되어있음
'011' '015' ==> 시작숫자 및 종료숫자가 '003' start1, '050' 사이에 포함되어잇음
'003' '050' ===> 종료숫자인 '050'이 '010' start1, '200' 사이에 포함되어있음
'080' '255' ==> 종료숫자인 '255'가 '201' start1, '255' 사이에 포함되어잇음
====
출력이 안된 '201' start1, '255'
'001' start1, '002'
는 어느 숫자 그룹에도 포함이 되지않아 출력이 안되는구조임
구간 중복 검색시 흔히 저지르게 되는 오류입니다. AND (a.s BETWEEN b.s AND b.e OR a.e BETWEEN b.s AND b.e) 이렇게 하면... B 를 기준으로 A 의 6가지 케이스별로 중복 체크를 해보면 B0 : s-----------e A1 : s-----e A2 : s-----e A3 : s-----e A4 : s-----e A5 : s-----e A6 : s----------------------------e 1, 2 는 중복이 안되구요 3,4,5,6 모두 중복이지만 위와 같은 조건으로는 6번이 누락이 됩니다. AND a.s < b.e AND a.e > b.s 이렇게 하시면 간결한 구문으로 모두 체크가 됩니다. 부등호에 이퀄(=)을 붙일지 안붙일지는 그때 상황에 맞게 판단하면 됩니다.
WITH w_ip AS ( SELECT 1 pk, '010' start1, '200' end1 FROM dual UNION ALL SELECT 2, '011', '015' FROM dual UNION ALL SELECT 3, '003', '050' FROM dual UNION ALL SELECT 4, '080', '255' FROM dual UNION ALL SELECT 5, '201', '255' FROM dual UNION ALL SELECT 6, '001', '002' FROM dual ) -- 0. 구간 중복 체크는 시작과 종료를 서로 교차비교하면 됩니다. -- 1. Self Join 후 중복 제거 SELECT DISTINCT a.pk, a.start1, a.end1 FROM w_ip a , w_ip b WHERE b.pk != a.pk AND b.start1 < a.end1 AND b.end1 > a.start1 ; -- 2. Exists 체크 SELECT * FROM w_ip a WHERE EXISTS (SELECT 1 FROM w_ip b WHERE b.pk != a.pk AND b.start1 < a.end1 AND b.end1 > a.start1 ) ;