Every Step Matters

[SQL] 서브 쿼리 (SubQuery) : (1) 기본 개념과 주요 예시 본문

Database/SQL

[SQL] 서브 쿼리 (SubQuery) : (1) 기본 개념과 주요 예시

imnyoung 2025. 12. 2. 23:24

1. 서브 쿼리란?

  • 하나의 SQL문 안에 포함되어 있는 SQL문
  • 서브 쿼리를 포함하는 SQL을 외부 쿼리(outer query) 또는 메인 쿼리라고 부르며, 서브 쿼리는 내부 쿼리(inner query)라고도 부른다.
  • ‘어떤 데이터를 가져와서 그 결과를 다시 조건이나 비교, 계산에 사용해야 하는 상황’을 단일 SQL문으로 해결하기 위한 도구이다.

 

2. 서브 쿼리의 종류

  • 중첩 서브 쿼리 : WHERE 절에 작성하는 서브 쿼리
  • 인라인 뷰 : FROM 절에 작성하는 서브 쿼리
  • 스칼라 서브 쿼리 : 단 하나의 값(1행 1열) 을 반환하는 서브쿼리로, 주로 SELECT 문에 작성
  • 상호연관 서브 쿼리 : 서브쿼리가 ‘혼자서’ 실행될 수 없고, 메인쿼리의 현재 행(row)에 의존해서 매번 다시 계산되는 서브쿼리. SELECT·FROM·HAVING 등 “외부쿼리의 컬럼을 참조할 수 있는 모든 위치”에서 사용 가능.

 

3. 서브 쿼리 사용 시 주의사항

  • 서브 쿼리는 반드시 괄호 '( )' 로 감싸서 사용해야 한다.
  • 서브 쿼리는 단일 행 비교 연산자('=', '<', '>' 등) 또는 다중 행 비교 연산자('in', 'any', 'all')와 함께 사용 가능하다.
    • 단일 행 비교연산자는 서브 쿼리의 결과가 1건 이하여야 한다.
    • 다중 행 비교연산자는 서브 쿼리의 결과 건수가 상관없다.

 

4. 서브 쿼리 사용 예시

1) 다른 쿼리 결과를 조건으로 사용해야 할 때

예: 전체 직원 중 최소 급여를 받는 직원만 조회하고 싶을 때

SELECT *
FROM employees
WHERE salary = (SELECT MIN(salary) FROM employees);

→ 서브쿼리가 없으면 최소 급여를 먼저 따로 구하고, 또 그걸 WHERE에 넣어야 한다.
SQL 한 문장에서 해결 불가.

2) 각 행마다 동적으로 계산된 값을 비교해야 할 때 (상호연관)

예: 부서별로 평균보다 높은 급여를 받는 직원 찾기

SELECT e.*
FROM employees e
WHERE e.salary > (
    SELECT AVG(salary)
    FROM employees sub
    WHERE sub.dept_id = e.dept_id  -- 부서 기준 연결. 메인 쿼리의 테이블을 사용하는 상호 연관 서브쿼리이다.
);

부서별 평균을 각각 따로 계산해 비교해야 하는 문제.
JOIN만으로 표현하기 매우 복잡해짐.

3) 집계 결과와 원본 데이터를 비교해야 할 때

예: 가장 매출이 높은 직원 조회

SELECT *
FROM employees
WHERE sales = (
    SELECT MAX(sales) FROM employees
);

집계 결과(최댓값/최솟값 등)와 특정 행을 연결하기 위해 필요.

4) GROUP BY 결과와 다시 비교해야 할 때

예: 부서별 평균 급여가 전체 평균보다 높은 부서 찾기

SELECT dept_id
FROM employees
GROUP BY dept_id
HAVING AVG(salary) > (
    SELECT AVG(salary) FROM employees
);

집계 결과 간의 비교를 편하게 해줌.

5) JOIN보다 의도를 더 명확하게 표현하고 싶을 때

일부 조건은 JOIN으로도 표현 가능하지만, 서브쿼리가 더 “내가 의도한 로직”을 직관적으로 보여주는 경우가 많다.

예: 특정 부서에 직원이 존재하는지 체크

SELECT *
FROM departments d
WHERE EXISTS (
    SELECT 1 FROM employees e WHERE e.dept_id = d.dept_id
);

EXISTS는 존재 여부를 매우 직관적으로 표현함.

6) 성능 최적화를 위해 (단, 특정 상황에 한함)

특히 EXISTS, NOT EXISTS, IN 등은 JOIN보다 더 빠른 경우가 종종 있다. (데이터 형태에 따라 다름).

예: 존재 여부만 확인하는 경우
JOIN보다 EXISTS가 훨씬 효율적.

 

 

 

 


Reference

[데이터리안] 데이터 분석을 위한 SQL 무료 강의