DBMS/개념

20_ 서브쿼리

seungwon-1 2025. 10. 18. 19:32

1. 서브쿼리가 필요한 이유

SQL에서 데이터를 조회하다 보면 단일 SELECT문만으로는 해결이 안 되는 경우가 많다.
예를 들어, “전체 평균보다 급여가 높은 직원만 조회하라” 같은 문제는
평균을 먼저 구하고, 그 결과를 다시 이용해야 한다.
이때 서브쿼리를 사용하면 한 번에 해결 가능하다.

서브쿼리는 코드의 간결성유연성, 그리고 동적 계산 능력을 동시에 제공한다.

 

 

2. 서브쿼리의 주요 유형

(1) 단일 행 서브쿼리 (Single Row Subquery)

  • 하나의 행(값)만 반환
  • =, <, >, <=, >= 같은 연산자와 함께 사용
SELECT first_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

전체 평균 급여보다 높은 급여를 받는 직원 조회.
서브쿼리가 한 개의 값을 반환하기 때문에 단일 행 서브쿼리에 해당한다.

 

 

(2) 다중 행 서브쿼리 (Multiple Row Subquery)

  • 여러 행을 반환
  • IN, ANY, ALL 같은 연산자와 함께 사용
SELECT first_name, salary
FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = 1700);

특정 지역(location_id = 1700)에 속한 부서의 직원들만 조회.

 

(3) 다중 열 서브쿼리 (Multiple Column Subquery)

  • 여러 열(column)을 동시에 반환
  • (col1, col2) 형태로 비교할 수 있음
SELECT employee_id, department_id
FROM employees
WHERE (department_id, salary)
      IN (SELECT department_id, MAX(salary)
          FROM employees
          GROUP BY department_id);

각 부서별 최고 급여를 받는 직원 찾기.

 

(4) 상관 서브쿼리 (Correlated Subquery)

  • 외부 쿼리의 컬럼을 참조하는 서브쿼리
  • 외부 쿼리의 각 행마다 서브쿼리가 반복 실행됨
SELECT e.employee_id, e.first_name, e.salary
FROM employees e
WHERE e.salary > (
    SELECT AVG(salary)
    FROM employees
    WHERE department_id = e.department_id
);

각 부서 평균보다 급여가 높은 직원 조회.
이때 e.department_id는 외부 쿼리의 값을 참조하므로, 상관 서브쿼리다.

 

3. 서브쿼리의 사용 위치

서브쿼리는 SQL 문 내 거의 모든 위치에서 쓸 수 있다.
각 위치마다 의미와 용도가 조금씩 다르다.

위치설명예시
SELECT 절 열 값을 동적으로 계산할 때 SELECT name, (SELECT MAX(price) FROM products)
FROM 절 인라인 뷰(임시 테이블)처럼 사용 FROM (SELECT ... ) AS temp
WHERE 절 조건 비교에 활용 WHERE salary > (SELECT AVG(...))
HAVING 절 그룹 결과에 조건 적용 HAVING AVG(salary) > (SELECT ...)

 

4. 실제 예시로 이해하기

(1) WHERE 절 — 평균보다 급여가 높은 직원

SELECT employee_id, first_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

평균 급여를 동적으로 계산해, 그보다 높은 직원만 필터링한다.

 

(2) FROM 절 — 인라인 뷰 활용

 
SELECT d.department_name, e.avg_salary
FROM departments d
JOIN (
    SELECT department_id, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department_id
) e
ON d.department_id = e.department_id;

 

(3) 상관 서브쿼리 — 부서 내 비교

SELECT e.employee_id, e.first_name, e.salary
FROM employees e
WHERE e.salary > (
    SELECT AVG(salary)
    FROM employees
    WHERE department_id = e.department_id
);

부서별 평균보다 급여가 높은 사람만 골라내는 쿼리.
각 부서마다 평균이 다르기 때문에 서브쿼리가 매번 실행된다.

 

5. 서브쿼리 사용할 때 주의할 점

  • 성능 이슈
    상관 서브쿼리는 행마다 실행되므로 느릴 수 있다.
    인덱스 설정이나 JOIN으로 대체할 수 있는지 검토해야 한다.
  • 가독성 저하
    서브쿼리가 너무 중첩되면 읽기 어렵다.
    이럴 땐 WITH문(CTE, Common Table Expression)을 쓰면 가독성이 좋아진다.
  • 대체 접근법 고려
    같은 결과를 JOIN, 윈도우 함수(OVER)로 구현할 수 있다면, 그쪽이 더 효율적인 경우가 많다.

 

6. 정리

구분반환 결과주요 연산자특징
단일 행 서브쿼리 1행 =, >, < 단일 값 비교
다중 행 서브쿼리 여러 행 IN, ANY, ALL 여러 결과 비교
다중 열 서브쿼리 여러 열 (col1, col2) IN 복합 조건 비교
상관 서브쿼리 매 행마다 실행 - 외부 쿼리 참조

'DBMS > 개념' 카테고리의 다른 글

22_ CTE (Common Table Expressions)  (0) 2025.10.22
21_ 집합 연산자  (0) 2025.10.20
19_ 조인(Join)  (0) 2025.10.16
18_ 조인(Join)과 서브쿼리(Subquery)  (0) 2025.10.14
17_ 뷰(view)  (0) 2025.10.11