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 |