반응형

서브쿼리는 쿼리 안에 또 다른 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
);
반응형

+ Recent posts