본문 바로가기

순이코딩/데이터베이스

[데이터베이스] SQL-서브쿼리(SUB QUERY)

728x90
반응형

1. 서브쿼리(SUB QUERY)

 

서브쿼리(SUB QUERY)다른 쿼리 안에 포함되어 있는 SELECT쿼리를 의미합니다. 보다 다양한 데이터를 출력하는 방법을 제공해 줍니다. 

 

■ 스칼라 서브쿼리

 

스칼라 서브쿼리는 SELECT에서 사용되는 서브쿼리로 하나의 컬럼에 대해 하나의 행만 반환하는 특징이 있습니다. 출력되는 하나의 값이 없다면 NULL값을 반환합니다.

스칼라 서브쿼리

스칼라 서브쿼리의 실행원리는 메인쿼리에서 출력되는 튜플의 수만큼 SELECT에 있는 서브쿼리가 반복실행됩니다.

이 스칼라 서브쿼리는 OUTER JOIN으로 대체 가능합니다.

OUTER JOIN

이렇게 스칼라 쿼리를 사용한 것과 OUTER JOIN의 결과 출력 창이 같습니다.

스칼라 서브쿼리를 사용할 때 주의사항이 있습니다. 스칼라 서브쿼리로 출력되는 행은 1개 혹은 NULL이어야 합니다. 또한 출력되는 컬럼도 1개여야 합니다.

 

■ 인라인 뷰(INLINE VIEW)

 

인라인 뷰는 FROM에서 사용되는 서브쿼리로 마치 가상의 테이블처럼 이용 가능한 서브쿼리입니다. 따로 떼어나서 실행해도 결과가 출력되는 독립적인 쿼리입니다.

 

■ 중첩 서브쿼리

 

중첩서브쿼리는 WHERE에서 주로 사용되는 서브쿼리로 메인쿼리와 관계가 있는지 없는지에 따라 상관 서브쿼리와 비상관 서브쿼리로 나뉩니다.

먼저 비상관 서브쿼리는 메인쿼리의 컬럼을 사용하지 않는 서브쿼리입니다. 그렇기 때문에 서브쿼리가 먼저 실행되고 메인 쿼리가 실행됩니다. 

비상관 서브쿼리

 

위의 비상관 서브쿼리는 먼저 직원의 평균연봉을 구한 뒤 그 평균연봉보다 높은 연봉을 받는 직원들의 전체 정보를 출력하고 있습니다. 독단적인 쿼리이므로 한 번의 실행을 통해 정답을 도출합니다.

상관 서브쿼리는 메인 쿼리의 컬럼을 사용하는 서브쿼리로 메인쿼리가 먼저 실행되고 서브 쿼리가 실행됩니다.

상관 서브쿼리

 

위의 상관 서브쿼리는 각 부서에서 연봉을 가장 적게 받는 사람들만 출력하고 있습니다. 메인 쿼리의 컬럼과 연관되어 있어 값이 정해져 있지 않습니다. 최소연봉만 출력하는게 아니라 메인쿼리의 부서ID를 참조해서 각 부서별로 최소연봉만 출력하고 있기 때문입니다.

 

■ 단일행/다중행 연산자

 

WHERE 절에서 서브쿼리 결과를 받을 때, 단일행을 받을 수 있는 연산자와 다중행을 받을 수 있는 연산자가 있습니다. 서브쿼리가 여러행을 출력하는 경우 단일행 연산자는 사용할 수 없습니다.

단일행 연산자는 =, >=, <, != 등 비교연산자입니다. 다중행 연산자는 IN, ANY, ALL, EXISTS, NOT EXISTS 등이 있습니다.

IN은 입력된 다중행 중에서 일치하는 값들은 모두 출력하는 연산자입니다.

IN 연산자 사용

 

위 그림에서 보듯 IN연산자를 사용하여 부서별 최대연봉인 직원들을 모두 출력하고 있습니다.

ANY 연산자는 입력된 다중 행 중에서 하나라도 일치하면 출력합니다. ANY의 원리는 OR와 같습니다. WHERE 연봉 >= ANY ( 5000, 7500, 2800); 이라고 했을 때, 연봉이 5000 이상 OR 연봉이 7500 이상 OR 연봉이 2800 이상인 직원들을 출력합니다.

ALL는 ANY와는 반대로 입력된 다중 행 중에서 값이 모두 일치해야 출력합니다. WHERE 연봉 >= ALL ( 5000, 7500, 2800);이라면 모두해당돼야 하기 때문에 결과적으로 연봉이 7500 이상인 사람만 출력합니다. ANY는 OR의 원리라면 ALL은 AND의 원리입니다. 

 

EXISTS는 입력된 다중 행 중에서 행의 존재 여부를 확인 하는 연산자입니다. 존재하면 TRUE를 반환합니다. EXISTS는 서브쿼리를 꼭 사용해야 하는 연산자입니다.

SELECT 직원ID, 이름
FROM 직원 A
WHERE EXISTS (
              SELECT 1
              FROM 직원연락처
              WHERE 직원ID = A.직원ID
              AND 연봉 = 7500) ;

 

IN은 일치하는 모든 것을 출력하기 위해 테이블의 모든 튜플에 접근하고 EXISTS는 일치하는 튜플이 있는 순간 해당작업을 중지합니다.

NOT EXISTS는 입력된 다중 행 중에서 일치하는 행의 존재 여부를 확인합니다. 존재하면 FALSE를 반환하고 조건과 일치하지 않는 내용에 대해 TRUE 출력합니다.

SELECT 직원ID, 이름
FROM 직원 A
WHERE NOT EXISTS(
                SELECT 1
                FROM 직원연락처
                WHERE 직원ID = A.직원ID) ;

NOT EXISTS를 이용한 위의 코드는 연락처가 존재하지 않는 직원만 출력했습니다.

728x90
반응형