분석함수를 이용한 기간중복 체크 0 5 1,245

by 김종석 [2019.06.06 19:10:38]



--> 원본테이블 ( 월 , 시작일 , 종료일)  
with t as (
select '1' as mm , 1 as sd , 1 as ed from dual union all
select '2' as col1 , 4 as sd , 6 as ed from dual union all 
select '3' as col1 , 11 as sd , 12 as ed from dual union all 
select '4' as col1 , 24 as sd , 25 as ed from dual union all 
select '5' as col1 , 24 as sd , 29 as ed from dual union all 
select '6' as col1 , 23 as sd , 23 as ed from dual union all 
select '7' as col1 , 2 as sd , 4 as ed from dual union all 
select '8' as col1 , 6 as sd , 11 as ed from dual union all 
select '9' as col1 , 12 as sd , 15 as ed from dual union all 
select '10' as col1 , 17 as sd , 17 as ed from dual union all
select '11' as col1 , 19 as sd , 19 as ed from dual union all
select '12' as col1 , 26 as sd , 29 as ed from dual   
)
select 
    *
    from 
    t

아래는 원본테이블에서 월별로 중복되는 근무일이 있는지 확인하는 쿼리인데 
셀프조인을 이용하였습니다. 혹시 깔끔하게 분석함수를 이용해서 같은결과를 
보여줄수 있나요? 
감사합니다. 

 

--> 셀프조인과 그룹바이를 이용한 결과 
with t as (
select '1' as mm , 1 as sd , 1 as ed from dual union all
select '2' as col1 , 4 as sd , 6 as ed from dual union all 
select '3' as col1 , 11 as sd , 12 as ed from dual union all 
select '4' as col1 , 24 as sd , 25 as ed from dual union all 
select '5' as col1 , 24 as sd , 29 as ed from dual union all 
select '6' as col1 , 23 as sd , 23 as ed from dual union all 
select '7' as col1 , 2 as sd , 4 as ed from dual union all 
select '8' as col1 , 6 as sd , 11 as ed from dual union all 
select '9' as col1 , 12 as sd , 15 as ed from dual union all 
select '10' as col1 , 17 as sd , 17 as ed from dual union all
select '11' as col1 , 19 as sd , 19 as ed from dual union all
select '12' as col1 , 26 as sd , 29 as ed from dual   
)
select 
    a.mm , a.sd , a.ed , listagg(b.mm ,',')within group (order by to_number(b.mm)) 중복월 
    from 
    t a left outer join t b 
            on a.mm <> b.mm(+) --> 월이 다르고 
            and ( a.sd between b.sd(+) and b.ed(+) or a.ed between b.sd(+) and b.ed(+) ) --> 날짜는 중복
    group by 
        a.mm , a.sd , a.ed           
         
    

by 마농 [2019.06.07 09:14:18]

1. 작성하신 셀프조인 조건은 부족한 조건입니다.
 - a 가 b 를 포함하는 경우는 찾질 못합니다.
 - 기간 검색은 시작과 종료를 서로 교차 비교하면 간단하게 해결됩니다.
 - 또한 아우터 조인 문법을 섞어 쓰셨네요. ANSI 조인에서는 (+)가 필요 없습니다.
 - AND a.sd <= b.ed
 - AND a.ed >= b.sd
2. 분석함수는
 - 이 문제에는 적당하지 않은 듯 합니다.
 - 위에 언급한 대로 조건을 주면 OR 절이 빠져서 간결해 보일 것입니다.


by 김종석 [2019.06.07 13:17:19]

감사합니다.  그렇게 간단히 되다니.. 전에 배운것도 같은데 . or 빠지면 안시 쿼리 안써도 되겠네요. 

근데 분석함수 쓰려는건 실제 원본 쿼리가 너무 길어서 셀프조인 쓰려면 with 문으로 뷰만들고 해야해서 많이 더욱 지저분해지거든요.  한번에 되는 분석함수방법은 없나요. 죄송합니다. 


by 마농 [2019.06.07 13:29:19]

사용 도구를 정해 놓고 결과를 도출하려고 하지 마시고
결과를 도출하기 위해 가장 적절한 방법이 뭔지를 찾아야 합니다.
도구를 정해 놓으면 사용가능한 방법의 가지수는 그만큼 줄어들고, 구현하기도 어려워질 수 있습니다.
복잡한 쿼리라는게 어떤 형태인가요?
WITH 문을 이용하면 복잡한 쿼리를 한번만 기술하는 것도 가능하고
아예 복잡한 쿼리 자체를 단순화 하는 것도 가능 할 수 있습니다.
지금 질문도 중간 결과집합을 이용해 다음 결과를 도출하는 질문을 하고 있는데.
이 또한 중간 집합이 아닌 원본을 가지고 질문한다면?
또 다른 기발한 해결방법을 찾을 수 도 있습니다.
복잡한 쿼리 보여주실 수 있는지요?


by 김종석 [2019.06.07 14:16:48]

죄송합니다. 망분리 되있어고 유출해도 되는지 모르겠고.  암튼 감사합니다


by 마농 [2019.06.07 14:24:07]

분석함수가 좋은 기능이긴 하지만, 만능은 아닙니다.
분석함수를 사용하기에 좋은 문제가 있을 것이고,
분석함수와는 상관없는 문제도 있을 것입니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입