반응형
서브쿼리는 쿼리 안에 또 다른 SELECT 쿼리가 포함된 구조로,
복잡한 데이터 처리를 간단하고 유연하게 해줍니다.
그 중에서도 자주 쓰이는 3가지 유형, 실습 예제와 함께 마스터해봅시다!
🔧 실습용 테이블 생성
-- 사원 테이블
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
emp_name VARCHAR(50),
dept_id INT,
salary INT
);
-- 부서 테이블
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(50)
);
-- 샘플 데이터
INSERT INTO departments VALUES (10, '개발부'), (20, '영업부'), (30, '인사부');
INSERT INTO employees VALUES
(1, '홍길동', 10, 5000),
(2, '김영희', 10, 6000),
(3, '이철수', 20, 5500),
(4, '박민수', 30, 4800),
(5, '최수지', 20, 6200);
1️⃣ 스칼라 서브쿼리 (Scalar Subquery)
하나의 값만 반환하는 서브쿼리를 칼럼처럼 사용하는 방식
SELECT emp_name,
salary,
(SELECT AVG(salary) FROM employees) AS avg_salary
FROM employees;
🧠 설명:
각 사원의 급여와 전체 평균 급여를 나란히 출력하는 예시입니다.
서브쿼리는 전체 평균 AVG(salary)를 계산해서 하나의 값(스칼라 값) 으로 반환합니다.
2️⃣ 인라인 뷰 (Inline View)
FROM 절에 사용되는 서브쿼리, 일시적인 테이블처럼 사용 가능
SELECT dept_id, avg_salary
FROM (
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id
) AS dept_avg;
🧠 설명:
이 쿼리는 부서별 평균 급여를 계산한 뒤,
해당 결과를 dept_avg라는 가상 테이블처럼 활용하는 구조입니다.
인라인 뷰 = 서브쿼리를 마치 테이블처럼 쓰는 것!
3️⃣ 중첩 서브쿼리 (Nested Subquery)
WHERE 절 안에 서브쿼리가 포함된 구조
SELECT emp_name, salary
FROM employees
WHERE dept_id = (
SELECT dept_id
FROM departments
WHERE dept_name = '개발부'
);
🧠 설명:
“개발부 소속 사원만 조회”하는 예시입니다.
부서 이름을 기준으로 dept_id를 찾고, 그 값을 메인 쿼리에 넘겨주는 방식!
한 번에 두 테이블을 JOIN 하지 않고, 단계적으로 필터링할 수 있는 장점이 있죠.
🔄 중첩 서브쿼리 – 단일행 vs 다중행
서브쿼리는 WHERE, HAVING, SELECT, FROM 절 등 어디서든 사용할 수 있지만,
그 중 WHERE 절에서 조건으로 쓰일 때, 반환되는 행의 수에 따라 나뉘어요
구분 | 반환값 | 비교 연산자 | 사용 예 |
단일행 서브쿼리 | 1행 1열 | =, >, <, >=, <=, != | 평균보다 높은 사원 찾기 |
다중행 서브쿼리 | 여러 행 | IN, ANY, ALL, EXISTS | 특정 조건의 부서에 속한 사원 찾기 |
🔸 단일행 서브쿼리 예제
전체 평균 급여보다 높은 급여의 사원 조회
SELECT emp_name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
📌 설명:
서브쿼리가 AVG(salary) 하나의 값을 반환 → salary > 단일값 비교 가능
👉 단일행 서브쿼리!
🔸 다중행 서브쿼리 예제 - IN
영업부와 인사부에 소속된 사원 조회
SELECT emp_name, dept_id
FROM employees
WHERE dept_id IN (
SELECT dept_id
FROM departments
WHERE dept_name IN ('영업부', '인사부')
);
📌 설명:
서브쿼리가 부서 ID 여러 개 반환 → IN으로 다중값 비교
👉 다중행 서브쿼리!
🔸 다중행 서브쿼리 예제 - ANY / ALL
모든 부서 중 최소 급여보다 높은 사원 찾기
SELECT emp_name, salary
FROM employees
WHERE salary > ALL (
SELECT MIN(salary)
FROM employees
GROUP BY dept_id
);
📌 설명:
employees를 부서별로 MIN(salary) 추출 → 여러 값 반환
> ALL (값1, 값2, 값3) → 그 모든 값보다 커야 참이 됨
👉 다중행 서브쿼리 + ALL 사용!
🧠 참고: ANY vs ALL 차이
연산자 | 의미 |
> ANY | 최소 하나보다 크면 됨 (최소조건 만족) |
> ALL | 모두보다 커야 함 (최대조건 만족) |
✅ 정리 요약표
유형 | 반환 행 수 | 대표 연산자 | 사용 위치 |
단일행 서브쿼리 | 1행 1열 | =, >, < 등 | WHERE, SELECT |
다중행 서브쿼리 | N행 | IN, ANY, ALL, EXISTS | WHERE, HAVING 등 |
✅ 마무리 요약
구분 | 위치 | 반환값 | 용도 |
스칼라 서브쿼리 | SELECT절 | 단일값 | 칼럼처럼 사용하여 부가 정보 붙일 때 사용 |
인라인 뷰 | FROM절 | 테이블 형태 | 서브쿼리 결과를 테이블처럼 가공하고 재사용 |
중첩 서브쿼리 | WHERE절 등 | 조건식에 사용 | 조건에 맞는 값을 찾아 필터링 |
🧪 실습 팁
- 서브쿼리는 항상 () 괄호로 감쌈
- 스칼라 쿼리는 반드시 단일 값을 반환해야 에러가 나지 않음
- 인라인 뷰는 alias 별칭 필수!
- 중첩 쿼리는 IN, EXISTS, = 등을 함께 자주 사용
🧠 실전 예제 더 보고 싶다면?
“부서 평균 급여보다 많이 받는 사원은?”
SELECT emp_name, salary
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE dept_id = e.dept_id
);
반응형
'자격증 > SQLD' 카테고리의 다른 글
ROLLUP / CUBE / GROUPING SETS / GROUPING 완전정복 (0) | 2025.05.12 |
---|---|
SQL 집합 연산자 완벽 가이드: UNION / UNION ALL / INTERSECT / MINUS(EXCEPT) (0) | 2025.05.12 |
조인(JOIN) (0) | 2025.05.06 |
🎯 SQLD 자격증 완벽 정리 — WHERE 절 완전 정복! (0) | 2025.05.06 |
📊 SQLD 자격증 완벽 대비 — SELECT 절의 모든 것 (0) | 2025.05.06 |