본문 바로가기

프로그램/oracle

[ORACLE]오라클 시작시간 종료시간에 포함되는 리스트 구하기

반응형

OKJSP 에 다음과 같이 질문이 올라왔길래 이에 대해 생각해봤다.

질문글 : http://www.okjsp.net/seq/250399

 

영화와 영화시작시간, 영화 종료시간이 존재하고

영화시작시간 혹은 종료시간이 중복되는 경우 이를 표시해야 한다.


결국은 시작시간 종료시간이 존재하고 해당 시간에 포함되는 모든 경우를 도출해라 가 될 것이다.

 

일단 테스트용으로 만들 TEMP테이블을 만들어야 하지만 걍 WITH로 대체

 

WITH TMP AS (

    SELECT 'A' AS TP

        , TO_DATE('201405141630', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405141830', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

    UNION ALL

    SELECT 'B' AS TP

        , TO_DATE('201405141830', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405142350', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

    UNION ALL

    SELECT 'C' AS TP

        , TO_DATE('201405141840', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405142300', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

)

 

겹치는 경우를 생각해봤다.

 

비교 주체 : ß---------à

비교할 대상 : ç=====è

 

1번 케이스 : 비교 주체의 시작시간과 종료시간이 비교대상을 포함한다.

    ß-------------------------à

         ç=======è

 

2번 케이스 : 비교 주체의 시간이 비교대상에 포함된다.

    ß------à

    ç============è

 

3번 케이스 : 비교주체의 시작시간 종료시간 안에 비교대상의 시작시간이 포함된다.

    ß----------à

        ç========è

 

4번 케이스 : 비교주체의 시작시간 종료시간 안에 비교대상의 종료시간이 포함된다.

       ß--------------à

    ç======è

 

위의 4개의 케이스를 조회한 후

이를 GROUP BY 걸면 결과가 나올 듯 하다는 생각이 들었다.

 

근데 4개 케이스를 조인 거니 쿼리가 많이 길어지는 단점이 있다.

 

WITH TMP AS (

    SELECT 'A' AS TP

        , TO_DATE('201405141630', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405141830', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

    UNION ALL

    SELECT 'B' AS TP

        , TO_DATE('201405141830', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405142350', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

    UNION ALL

    SELECT 'C' AS TP

        , TO_DATE('201405141840', 'YYYYMMDDHH24MI') AS SD

        , TO_DATE('201405142300', 'YYYYMMDDHH24MI') AS ED

    FROM DUAL

)

SELECT T_TP, TP

FROM ( 

    SELECT A.TP AS T_TP, A.SD AS T_SD, A.ED AS T_ED, B.TP, B.SD, B.ED

    FROM TMP A

        , TMP B

    WHERE A.SD BETWEEN B.SD AND B.ED

    AND A.TP != B.TP

    UNION ALL

    SELECT A.TP AS T_TP, A.SD AS T_SD, A.ED AS T_ED, B.TP, B.SD, B.ED

    FROM TMP A

        , TMP B

    WHERE A.ED BETWEEN B.SD AND B.ED

    AND A.TP != B.TP

    UNION ALL

    SELECT A.TP AS T_TP, A.SD AS T_SD, A.ED AS T_ED, B.TP, B.SD, B.ED

    FROM TMP A

        , TMP B

    WHERE A.SD < B.SD AND A.ED > B.ED

    AND A.TP != B.TP

    UNION ALL

    SELECT A.TP AS T_TP, A.SD AS T_SD, A.ED AS T_ED, B.TP, B.SD, B.ED

    FROM TMP A

        , TMP B

    WHERE A.SD > B.SD AND A.ED < B.ED

    AND A.TP != B.TP

)

GROUP BY T_TP, TP

ORDER BY T_TP, TP

 

결과과 어느정도는 일치하게 나오는 듯 한데 정확한 건 데이터가 테스트로 3건만 넣어서 확실히는 모르겠다.

 

근데 저렇게 셀프조인을 애매하게 조건 넣어서 하면 시간이 엄청 걸릴 꺼 같은 생각도 든다.

 

나중에 비슷한 경우가 생기면 한번 해봐야 겠다.