ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL BOOSTER - 서브쿼리 (WHERE)
    DataBase/SQL 2024. 6. 23. 15:33

     

     

    1. WHERE절 단독 서브쿼리

     

    서브쿼리는  WHERE 절에서도 단독으로 사용할 수 있다.

     

    1.1 마지막 한 건 조회하기 

    SELECT * 
    FROM T_ORD T1
    WHERE T1.ORD_SEQ = (SELECT MAX(A.ORD_SEQ) FROM T_ORD A);

     

    위 SQL은 T_ORD 테이블을 두 번 사용하고 있다. SQL의 성능을 위해서는 테이블의 반복 출현을 줄여야한다. 

     

    따라서 위 SQL은 아래와 같이 사용하는 것이 성능 면에서 좀 더 유리할 수 있다.

     

    -- order by와 rownum 활용
    SELECT *
    FORM (
       SELECT *
       FROM T_ORD T1
       ORDER BY T1.ORD_SEQ DESC
       )A
    WHERE ROWNUM <= 1;

     

    • ORDER BY와 ROWNUM을 사용한 방법이다. -> 해당 방법에서 성능에 이득을 보려면, ORD_SEQ에 대한 인덱스가 필수이다. T_ORD 테이블은 ORD_SEQ가 PK이므로 이미 인덱스가 존재한다. (PK에는 기본적으로 UNIQUE 인덱스가 생성된다) 

     

    1.2 마지막 일자 주문 조회하기 

     

    마지막 주문 일자를 조회하는 SQL이다.

    SELECT * FROM T_ORD T1
    WHERE T1.ORD_DT = (SELECT MAX(ORD_DT) FROM T_ORD A);

     

    위  SQL은 성능을 위해 ORD_DT 칼럼에 인덱스가 필요할 수 있다.

     

    1.3 IN조건에 서브쿼리 사용하기 

    SELECT *
    FROM T.ORD T1
    WHERE T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
    AND T1.ORD_DT < TO_DATE('20170401','YYYYMMDD')
    AND T1.CUS_ID ID (
                        SELECT A.CUS_ID 
                        FROM T.ORD A
                        WHERE A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
                        AND A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
                        GROUP BY A.CUS_ID
                        HAVING COUNT(*) >= 4);

     

    --인라인 뷰를 활용하기
    SELECT T1.*
    FORM T_ORD T1, (
                     SELECT A.CUS_ID
                     FROM T_ORD A
                     WHERE A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
                     AND A.ORD_DT < TO_DATE ('20170401','YYYYMMDD')
                     GROUP BY A.CUS_ID
                     HAVING COUNT(*) >=4
                     )T2
    WHERE T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
    AND   T1.ORD_DT < TO_DATE ('20170401','YYYYMMDD')   
    AND   T1.CUS_ID = T2.CUS_ID;
    • 위 SQL은 중복된 데이터를 찾아낼 때도 유용하게 사용할 수 있는 패턴이다. 
    • 서브쿼리 안에서  GROUP BY를 한 이유는 쿼리 결과로 조건에 해당하는 모든 데이터 출력을 위함

    2. WHERE절 상관 서브쿼리 

     

    WHERE 절의 상관 서브쿼리는 데이터의 존재 여부를 파악할 때 자주 사용한다.

    예를 들어 특정 일자나 특정 월에 주문이 존재하는 고객 리스트 같은 것을 뽑을 때 유용하다.

     

    SELECT *
    FROM M_CUS T1
    WHERE EXISTS(
               SELECT *
               FROM T_ORD A
               WHERE A.CUS_ID = T1.CUS_ID
               AND A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
               AND A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
               );
    • 위 SQL은 3월에 주문이 한 건이라도 존재하는 고객을 조회한다. 반대로 주문이 한 건도 없는 고객을 조회해야 한다면, NOT EXISTS를 사용하면 된다. 이처럼 WHERE 절의 상관 서브 쿼리는 다른 테이블에 데이터 존재 여부를 파악할 때 유용하다. 

    WHERE절 서브쿼리 안에서도 조인을 사용할 수 있다. 

    SELECT * 
    FROM M_CUS T1
    WHERE EXISTS(
              SELECT *
              FROM T_ORD A
                   ,T_ORD_DET B
                   ,M_ITM C
              WHERE A.CUS_ID = T1.CUS_ID
              AND A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
              AND A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
              AND A.ORD_SEQ = B.ORD_SEQ
              AND B.ITM_ID = C.ITM_ID
              AND C.ITM_TP = 'ELEC');
    • 3월에 아이템 유형이 ELEC인 주문이 한 건이라도 존재하는 고객 정보를 조회하는 쿼리이다. 

     

    *참고 EXISTS는 SELECT절의 서브쿼리에도 사용이 가능함 

    고객 리스트 조회 + 고객의 3월 주문 존재 여부를 YN으로 보여주어야 한다면, 다음과 같이 작성할 수 있다.

     

    SELECT T1.CUS_ID, T1.CUS_NM, 
                                (CASE WHEN 
                                         EXISTS(
                                            SELECT *
                                            FROM T_ORD A
                                            WHERE A.CUS_ID = T.CUS_ID
                                            AND A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
                                             AND A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
                                             )
                                  THEN 'Y'
                                  ELSE 'N' END) ORD_YM_03
       FROM M_CUS T1;
    • CASE문과 EXISTS절을 사용해 3월에 주문이 존재하면 Y 주문이 없으면 N이 조회되도록 처리하고 있다.
    • 위 SQL은 인라인 뷰와 아우터 조인을 사용해 해결할 수도 있는데, 어떤 방법이던지 성능에 차이가 존재할 수 있다 SQL 작성과 함께 조회될 고객과 주문의 건수 그리고 인덱스에 따라 성능 차이가 발생한다. 

     


    참고자료

    https://www.yes24.com/Product/Goods/82818767

     

    SQL BOOSTER - 예스24

    SQL BOOSTER는 프로젝트 성공을 위한 SQL 필독서다. 이 책은 마치 프로젝트를 진행하는 순서처럼 구성되어 있다. 프로젝트 투입을 위해 필요한 SQL 기술을 설명하고, 성능 테스트를 위해 필요한 기술

    www.yes24.com

     

    'DataBase > SQL' 카테고리의 다른 글

    SQL BOOSTER - MERGE 조인과 성능  (0) 2024.06.24
    SQL BOOSTER - MERGE  (0) 2024.06.23
    SQL BOOSTER - 서브쿼리 (SELECT)  (0) 2024.06.23
    SQL BOOSTER - OUTER JOIN  (0) 2024.06.20
    SQL BOOSTER - NL조인과 성능  (0) 2024.06.12
Designed by Tistory.