ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SQL] SUB QUERY
    Data miner/Development log 2023. 4. 6. 16:11
    728x90

     

     

    서브 쿼리의 종류 

    - 서브쿼리는 QUERY OF QUERY 로 메인 쿼리의 각 부분 파트에 또 다른 쿼리문이 있는 형태다. 별도로 괄호로 묶은 쿼리 블록으로 표현된다. SQL 옵티마이저는 서브쿼리를 참조하는 메인 쿼리 블록을 포함하여, 쿼리 블록 단위로 쿼리 최적화를 수행한다.

     

    1) SELECT 문에 SUB QUERY가 있는 경우

    - 스칼라 서브쿼리라고 불림

    - 하나의 레코드 당 하나의 값을 반환하는 서브 쿼리

    - 주의할 점 : 데이터 양이 많으면, 실행속도가 느려짐

     

     

    2) FROM 문에 SUB QUERY가 있는 경우

    - 테이블 처럼 사용됨. 인라인뷰 서브쿼리라고 불림

    ex)

    SELECT c.고객번호, c.고객명
    FROM 고객테이블 c,
    	(SELECT 고객번호, avg(거래금액) 평균거래
        ,min(거래금액) 최소거래, max(거래금액) 최대거래
        FROM 거래테이블
        WEHRE 거래날짜 >= trnc(sysdate, 'mm')
        GROUPBY 고객번호) t
    WHERE c.가입일시 >= trnc(add_months(sysdate, -1), 'mm')
    AND t.고객번호 = c.고객번호

     

     

    3) WHERE 문에 SUB QUERY가 있는 경우

    - 결과 집합을 한정하기 위해 WHERE 절에 사용한 서브 쿼리

    - 서브 쿼리가 메인 쿼리를 참조한다면, 상관관계(Corelated) 서브 쿼리라고 함

    SELECT c.고객번호, c.고객명
    FROM 고객테이블 c
    WHERE c.가입일시 >= trunc(add_months(sysdate, -1), 'mm')
    and exists (SELECT 'x'
    			FROM 고객변경이력 h
                WHERE h.고객번호 = c.고객번호
                and h.변경사유코드 = 'zbc')

     

     

    서브쿼리와 조인

    - 메인 쿼리와 서브 쿼리 간에는 부모와 자식이라는 종속적이고 계층적인 관계가 존재. 서브쿼리는 메인쿼리에 종속되므로 단독으로 실행할 수 없음

     

    필터오퍼레이션

    SELECT c.고객번호, c.고객명
    FROM 고객테이블 c,
    WHERE c.가입일시 >= trnc(add_months(sysdate, -1), 'mm')
    AND exists 
    	(SELECT /*+ no_unnest */ 'x'
        from 거래정보 t
        where t.고객번호 = c.고객번호
        and t.거래일시 >= trunc(sysdate, 'mm'))

    - /*+ no_unnest */ 힌트 사용

    - 기본적으로 NL 조인과 처리 루틴이 같음.

    1) 다만, 메인쿼리(고객)의 한 로우가 서브쿼리(거래)의 한 로우와 조인에 성공하면 탐색 진행을 멈추고(inner loop exit), 메인쿼리의 다음 로우를 계속 처리함

    2) 메인쿼리 결과집합이 서브쿼리 결과집합으로 확장되어 고객정보가 중복되는 현상을 막을 수 있음

    - NL조인과 다른 점은 이 필터 기능이 캐싱기능을 가짐. 서브쿼리 입력값에 대한 반환값(T/F)를 가져서 서브쿼리를 수행하기 전에 캐시부터 확인함

    - 필터 서브쿼리는 메인 쿼리에 종속되며, 메인쿼리가 드라이빙 집합인 순서로 조인 순서가 고정됨

     

    서브쿼리 Unnesting

    -  중첩구조를 포개넣지 않는다 (unnest). 중첩구조를 풀어낸다는 의미. 즉, 메인쿼리와 서브쿼리의 계층적인 상태가 아닌 두 쿼리를 동일선상에서 처리하겠다는 뜻

    - 서브쿼리를 메인쿼리와 같은 계층에 넣게 되면, 서브쿼리 쪽 집합 수준으로 확장되지 않게 유의해야 한다.

    - unnesting되지 않은 서브쿼리는 위의 필터 방식으로 항상 처리 됨

     

    서브쿼리 Pushing

    - Unnesting되지 않은 서브쿼리에 한해, 서브쿼리 필터링 가능한 한 앞단계에서 강제 

    - push_subq/no_push_subq 힌트를 사용, no_unnest힌트와 함께 사용한다

    ex) /*+ no_unnest push_subq */

     

     

     

    *sysdate - 현재날짜와 시간 정보 알려줌

    *trunc('2023-04-05 00:00:00', 'mm') - '월'만 추출

     

     

     

Designed by Tistory.