SQL 하위 쿼리(Sub-query)

하위 쿼리(Sub-query)란 하나의 SQL문장에 속하는 또 다른 SQL문장으로, 두 번 이상의 질의를 통해 얻을 수 있는 결과를 한 번의 질의로 해결할 수 있다. 하위 쿼리를 사용하면 복잡한 SQL문장도 간단히 만들 수 있고, DBMS의 데이터 처리 속도도 빠르게 향상시킬 수 있다.


FROM절의 하위 쿼리

실무에서 하위 쿼리를 사용할 때는 FROM절에서 크게 두 가지의 용도로 나눌 수 있다.

첫 번째는 조건에 맞는 대상자를 선정한 후 요약할 때 사용되고, 두 번째는 조인할 때 사용된다.

 

첫 번째 용도로 하위쿼리를 사용할 때는 하위 쿼리를 작성한 후 테이블 별칭을 꼭 주어야 한다. 이때 테이블 별칭을 주지 않으면 에러가 발생한다는 점이다.  테이블 별칭을 줄 때 AS 키워드를 사용해도 되고 생략해도 된다. 단, DBMS 중 ORACLE은 테이블 별칭을 줄 때 AS키워드를 지원하지 않는 점을 기억해야 한다.

 

 

1.조건에 맞는 대상자 선정 후 요약할 때

SELECT 열 이름1, 열 이름2
FROM(SELECT * FROM 테이블명 WHERE 조건절) (AS) 별칭
WHERE 조건절;  --(별칭1.열 이름1 = 별칭2.열 이름2 같은거 )

위 방법은 조건에 맞는 대상자를 선정한 후 데이터를 요약할 때 많이 사용되는 방법이다. 테이블에 별칭을 줄 때는 AS는 생략 가능하다. 단 ORACLE에서는 테이블 별칭을 줄 때 AS키워드를 반드시 생략해야 한다.

 

 

2.테이블 조인을 할 때

SELECT 별칭1.열 이름1, 별칭2.열 이름2
FROM 테이블명1 (AS) 별칭1 LEFT OUTER JOIN
(SELECT 열 이름1, 열 이름2 FROM 테이블명2 WHERE 조건절) (AS) 별칭2
ON 별칭1.KEY=별칭2.KEY;

테이블 조인을 할 때 필요한 정보만 조인할 수 있도록 고안된 방법이다.

 

 

 

추가

1.데이터 분석 시 키값이 되는 열들은 중복 없이 나열하고, 좀 더 자세히 분석하려는 대상은 옆으로 붙이는 것이 매우 중요하다.

 

2.중복을 제거한 형태의 테이블을 만든 후 조인해야 한다.

중복을 제거하지 않고 테이블을 조인하면 오류가 발생할 확률이 높아지기 때문이다.


WHERE 조건절의 하위 쿼리

`WHERE 조건절`에서 하위 쿼리는 `IN연산자`와 함께 쓰인다고 생각하면 된다.

단일 결과값인 경우 '='를 사용할 수도 있지만 IN연산자가 포괄적 기능을 하기 때문에 WHERE조건절의 하위 쿼리는 IN과 함께 사용한다고 외우면 된다. (단일 행에서 하위 쿼리는 IN대신 '='를 사용할 수 있다.) 전체 모집단에서 특정 세그먼트만 추출할 때 WHERE 조건절의 하위 쿼리가 유용하게 사용된다. 즉, 테이블명1에서 테이블명2의 결과를 출력하고 싶을 때 사용한다.

 

1.단일 행 서브쿼리

EX)employees 테이블의 last_name이 'De Haan'인 직원과 salary가 동일한 직원에는 누가 있는지 단일 행 서브쿼리를 이용해 출력

SELECT *
FROM employees A
WHERE A.salary = (
                   SELECT salary
                   FROM employees
                   WHERE last_name = 'De Haan'
                 );

 

2.다중 행 서브쿼리

SELECT 열 이름1, 열 이름2
FROM 테이블명1
WHERE 열 이름 IN (SELECT 열 이름 FROM 테이블명2 WHERE 조건절);

열 이름 뒤에 IN을 사용하여 필요한 데이터만 가져올 수 있는 방법이다.

 

다중 행 연산자 설명
IN 같은 값 IN(10,20) -> 10이나 20 포함
NOT IN 같은 값이 아님 NOT IN(10,20) -> 10이나 20이 포함되지 않는다.
EXISTS 값이 있으면 반환 EXISTS(10) -> 10이 존재하면 참
ANY 최소한 하나라도 만족하는 것(OR)
<, =등 비교 연산자와 같이 사용
ANY(10,20) -> 10이나 20이 포함
ALL 모두 만족하는 것(AND)
<, =등 비교 연산자와 같이 사용
ALL(10,20) -> 10과 20이 포함

 

EX)employees 테이블에서 department_id별로 가장 낮은 salary가 얼마인지 찾아보고, 찾아낸 salary에 해당하는 직원이 누구인지 다중 행 서브쿼리를 이용해 출력

SELECT *
FROM employees A
WHERE A.salary IN(    --여기서 IN이 다중 행 연산자
                  SELECT MIN(salary) 최저급여
                  FROM employees
                  GROUP BY department_id
                  )
ORDER BY A.salary DESC;

 

3.다중 열 서브트리

다중 열 서브쿼리는 메인 쿼리와 서브쿼리를 비교하는 WHERE 조건식에서 비교되는 열이 여러 개일 때 사용하는 서브쿼리입니다.

SELECT 열 이름
FROM 테이블 이름
WHERE(열 이름1, 열 이름2, ...) IN (SELECT 열 이름1, 열 이름2, ...  --비교되는 열이 여러 개
                                   FROM 테이블 이름
                                   WHERE 조건식);

 

EX)employees 테이블에서 job_id별로 가장 낮은 salary가 얼마인지 찾아보고, 찾아낸 job_id별 salary에 해당하는 직원이 누구인지 다중 열 서브쿼리를 이용해 출력

SELECT *
FROM employees A
WHERE (A.job, A.salary) IN (
                            SELECT job_id, MIN(salary) 그룹별급여
                            FROM employees
                            GROUP BY job_id
                            )
ORDER BY A.salary DESC;