더북(TheBook)

연관성 있는 서브 쿼리

메인 쿼리와의 연관성이 있는 서브 쿼리, 즉 메인 테이블과 조인 조건이 걸린 서브 쿼리를 말한다.

입력

    SELECT a.department_id, a.department_name
      FROM departments a
     WHERE EXISTS ( SELECT 1
                      FROM job_history b
                     WHERE a.department_id = b.department_id );

결과

    DEPARTMENT_ID DEPARTMENT_NAME
    ------------- -----------------
    20            마케팅
    50            배송부
    60            IT
    80            영업부
    90            기획부
    110           경리부

    6개의 행이 선택됨

이 쿼리는 연관성 있는 서브 쿼리로 서브 쿼리 안에서 메인 쿼리에서 사용된 부서 테이블의 부서번호와 job_history 테이블의 부서번호가 같은 건을 조회하고 있다. 또한 EXISTS 연산자를 사용해서 서브 쿼리 내에 조인 조건이 포함되어 있다. 따라서 결과는 job_history 테이블에 있는 부서만 조회되었다. 또 다른 형태를 살펴 보자.

입력

    SELECT a.employee_id,
           ( SELECT b.emp_name
               FROM employees b
              WHERE a.employee_id = b.employee_id) AS emp_name,
           a.department_id,
           ( SELECT b.department_name
               FROM departments b
              WHERE a.department_id = b.department_id) AS dep_name
    FROM job_history a;

결과

    EMPLOYEE_ID EMP_NAME                 DEPARTMENT_ID DEP_NAME
    ----------- ------------------------ ------------- ------------
    102         Lex De Haan              60            IT
    101         NeenaKochhar             110           경리부
    101         NeenaKochhar             110           경리부
    201         Michael Hartstein        20            마케팅
    114         Den Raphaely             50            배송부
    122         PayamKaufling            50            배송부
    200         Jennifer Whalen          90            기획부
    176         Jonathon Taylor          80            영업부
    176         Jonathon Taylor          80            영업부
    200         Jennifer Whalen          90            기획부

    10개의 행이 선택됨

이 쿼리는 job_history 테이블을 조회하고 있는데 job_history에는 사번, 부서번호만 존재하므로 사원명과 부서명을 가져오려고 서브 쿼리를 SELECT 절에서 사용하였고 서브 쿼리 안의 WHERE 절에 조건을 추가했다. 이처럼 SELECT 절 자체에도 여러 개의 서브 쿼리를 넣을 수 있다. 또한 각 서브 쿼리가 독립적이므로 두 개의 서브 쿼리에서 사용된 사원, 부서 테이블의 별칭을 모두 b로 사용해도 무방하다. 또 다른 예를 살펴 보자.

입력

    SELECT a.department_id, a.department_name
      FROM departments a
     WHERE EXISTS ( SELECT 1
                      FROM employees b
                     WHERE a.department_id = b.department_id → ①
                       AND b.salary > ( SELECT AVG(salary) → ②
                                          FROM employees )
                   );

결과

    DEPARTMENT_ID DEPARTMENT_NAME
    ------------- -----------------
    20            마케팅
    30            구매/생산부
    40            인사부
    50            배송부
    60            IT
    70            홍보부
    80            영업부
    90            기획부
    100           자금부
    110           경리부

    10개의 행이 선택됨

이 쿼리에서는 2개의 서브 쿼리가 사용되었다. 먼저 ②에서 평균급여를 구하고 이 값보다 큰 급여의 사원을 걸러낸 다음(연관성 없는 서브 쿼리), ①에서 평균급여 이상을 받는 사원이 속한 부서를 추출한 것(연관성 있는 서브 쿼리)이다. 이처럼 서브 쿼리는 여러 단계에 걸쳐 사용이 가능하다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.