Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 날짜 포맷
- ifnull
- order by
- Python
- 해외결제
- count
- SubQuery
- inner join
- is null
- MAX
- SQL
- 투자자산운용사
- alias
- GROUP BY
- 트래블테크
- having
- Round
- programmers
- 서브쿼리
- 도서추천
- IELTS
- 금융IT
- IS NOT NULL
- IN
- MySQL
- LIMIT
- 금융 플랫폼
- date_format
- join
- where
Archives
- Today
- Total
Every Step Matters
[SQL] 서브 쿼리 (SubQuery) : (1) 기본 개념과 주요 예시 본문
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
'Database > SQL' 카테고리의 다른 글
| [프로그래머스 SQL Lv.2] 중복 제거하기 (MySQL) (0) | 2025.12.03 |
|---|---|
| [프로그래머스 SQL Lv.2] 동물 수 구하기 (MySQL) (0) | 2025.12.03 |
| [프로그래머스 SQL Lv.1] 잡은 물고기의 평균 길이 구하기 (MySQL) (0) | 2025.12.02 |
| [프로그래머스 SQL Lv.1] 나이 정보가 없는 회원 수 구하기 (MySQL) (0) | 2025.12.02 |
| [프로그래머스 Lv.2] NULL 처리하기 (MySQL) (0) | 2025.12.02 |