목차
4. 서브쿼리
4-1. 서브쿼리의 종류
4-1-1. 위치에 따른 구분
4-1-2. 메인 쿼리와의 관계에 따른 구분
4-2. 중첩 서브쿼리
4. 서브쿼리
서브쿼리란 쿼리 안에 또 다른 쿼리가 들어있는 형태를 말한다.
쉽게 말해서 메인 쿼리가 실행되기 전에 필요한 데이터를 먼저 조회하는 작은 쿼리라고 생각할 수 있다.
4-1. 서브쿼리의 종류
1️⃣ 서브쿼리의 위치에 따른 구분
| 종류 | 서브쿼리가 들어가는 위치 |
| 스칼라 서브쿼리 | SELECT문의 컬럼 입력 위치 |
| 인라인 뷰 | FROM절의 테이블 입력 위치 |
| 중첩 서브쿼리 | WHERE절, HAVING절의 컬럼 또는 테이블 입력 위치 |
🔹 스칼라 서브쿼리
SELECT 절에서 하나의 값을 조회할 때 사용한다.
SELECT
EMP_NAME,
(SELECT AVG(SALARY) FROM EMP) AS AVG_SALARY
FROM EMP;
🔹 인라인 뷰
FROM 절에서 임시 테이블처럼 사용하는 서브쿼리이다.
SELECT *
FROM
(
SELECT *
FROM EMP
WHERE DEPTNO = 10
) A;
🔹 중첩 서브쿼리
WHERE 절이나 HAVING 절에서 조건을 만들기 위해 사용하는 서브쿼리이다.
SELECT *
FROM EMP
WHERE SALARY >
(
SELECT AVG(SALARY)
FROM EMP
);
2️⃣ 메인쿼리의 컬럼 사용 여부에 따른 구분
| 종류 | 설명 |
| 연관(Correlated) 서브쿼리 | 메인쿼리의 컬럼을 서브쿼리에서 사용 |
| 비연관(Un-Correlated) 서브쿼리 | 메인쿼리의 컬럼을 서브쿼리에서 사용하지 않음 |
🔹 연관 서브쿼리
메인 쿼리의 컬럼을 참조하면서 실행되는 서브쿼리이다.
메인 쿼리의 각 행마다 서브쿼리가 반복 실행된다.
SELECT *
FROM EMP E
WHERE SALARY >
(
SELECT AVG(SALARY)
FROM EMP
WHERE DEPTNO = E.DEPTNO
);
➜ 메인 쿼리의 E.DEPTNO를 서브쿼리에서 사용하고 있으므로 연관 서브쿼리이다.
🔹 비연관 서브쿼리
메인 쿼리의 컬럼을 참조하지 않는 서브쿼리이다.
서브쿼리가 한 번 실행된 결과를 메인 쿼리에서 사용한다.
SELECT *
FROM EMP
WHERE SALARY >
(
SELECT AVG(SALARY)
FROM EMP
);
4-2. 중첩 서브쿼리
중첩 서브쿼리란 WHERE절이나 HAVING절 안에 또 다른 쿼리가 들어있는 형태를 말한다.
중첩 서브쿼리는 반환되는 결과의 형태에 따라 단일행, 다중행, 다중컬럼 서브쿼리로 구분한다.
| 반환값 유형 | 설명 |
| 단일행 | 조회 결과가 1행 이하인 경우. 단일행 비교연산자(=, >, >=, <, <=, <>)와 함께 사용한다. |
| 다중행 | 조회 결과가 여러 행인 경우, 다중행 비교 연산자(IN, ANY, SOME, ALL, EXISTS)와 함께 사용한다. |
| 다중컬럼 | 조회 결과가 여러 개의 컬럼인 경우, 여러 컬럼을 하나의 조건으로 비교할 때 사용한다. |
1️⃣ 단일행
조회 결과가 1건 이하인 서브쿼리이다.
단일행 비교 연산자인 =, >, >=, <, <=, <> 등을 사용할 수 있다.
🔹 예제

SELECT EMPNO,
ENAME,
SAL
FROM EMP
WHERE SAL >= (SELECT AVG(E.SAL) FROM EMP E);
➜ 먼저 서브쿼리에서 평균 급여를 구한 후,
메인 쿼리에서 평균 급여 이상인 사원을 조회한다.
🔹 실행결과

2️⃣ 다중행
조회 결과가 여러 행인 서브쿼리이다.
다중행 비교 연산자인 IN, ANY, SOME, ALL, EXISTS 등을 사용한다.
🔹 예제

SELECT EMPNO,
ENAME,
SAL,
DEPTNO
FROM EMP
WHERE DEPTNO IN (SELECT DISTINCT DEPTNO
FROM EMP
WHERE SAL <= 1000);
➜ 급여가 1000 이하인 사원이 속한 부서 번호를 먼저 조회한 뒤,
그 부서에 속한 모든 사원을 조회한다.
🔹 실행결과

📌 SQLD에서는 'IN' 연산자가 가장 자주 출제되므로 반드시 익혀두자.
3️⃣ 다중컬럼
조회 결과가 여러 개의 컬럼으로 반환되는 서브쿼리이다.
여러 컬럼을 하나의 조건으로 비교할 때 사용한다.
🔹 예제

SELECT EMPNO, ENAME, JOB, SAL
FROM EMP
WHERE (JOB, SAL) IN (SELECT JOB, MAX(SAL)
FROM EMP
GROUP BY JOB);
➜ 직무(JOB)별 가장 높은 급여(MAX(SAL))를 가진 사원을 조회하는 예제이다.
(JOB, SAL)처럼 두 개 이상의 컬럼을 하나의 묶음으로 비교한다.
🔹 실행결과
