MySQL에서 복잡한 조건의 데이터를 추출하거나, 다른 테이블의 데이터를 기준으로 조회해야 할 때는 서브쿼리(Subquery)를 활용하면 매우 유용하다.
서브쿼리는 SELECT문 안에 포함된 또 다른 SELECT문으로, 필터링, 정렬, 조건 분기, 집계 등 다양한 상황에서 강력한 기능을 제공한다.
📌 서브쿼리란 무엇인가
서브쿼리(Subquery)란 하나의 쿼리문 안에서 또 다른 SELECT 쿼리를 실행하는 것을 말한다. 주로 WHERE, FROM, SELECT 절 안에서 사용되며, 기준값을 동적으로 설정할 수 있는 장점이 있다.
서브쿼리는 다음과 같이 분류할 수 있다.
- 스칼라 서브쿼리: 하나의 값만 반환
- 인라인 뷰 (FROM절 서브쿼리): 임시 테이블처럼 사용
- 상관 서브쿼리 (Correlated Subquery): 외부 쿼리 값을 내부 쿼리에서 참조
🔍 WHERE 절에서의 서브쿼리 – 조건 필터링에 활용
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
이 쿼리는 전체 평균 급여보다 높은 사원만 조회하는 예제다. 내부 쿼리로 평균 급여를 계산한 후, 외부 쿼리에서 그 값을 조건으로 사용한다.
🔍 FROM 절에서의 서브쿼리 – 가상의 테이블 만들기
SELECT dept_avg.department_id, dept_avg.avg_salary
FROM (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) AS dept_avg
WHERE dept_avg.avg_salary > 5000;
이 예제는 부서별 평균 급여가 5000을 초과하는 부서를 조회한다. FROM절에서 서브쿼리를 사용해 임시 테이블(인라인 뷰)을 생성한 후, 외부 쿼리에서 필터링한다.
🔍 SELECT 절에서의 서브쿼리 – 추가 컬럼 동적 조회
SELECT name,
(SELECT COUNT(*) FROM orders WHERE orders.user_id = users.user_id) AS order_count
FROM users;
각 회원이 몇 번의 주문을 했는지 함께 조회할 수 있다. SELECT 절에서 서브쿼리를 활용해, 보조 컬럼처럼 추가 정보를 동적으로 계산하는 방식이다.
🧠 상관 서브쿼리(Correlated Subquery) – 외부 쿼리 참조
SELECT name
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);
이 쿼리는 각 부서별 평균 급여보다 높은 급여를 받는 사원만 조회한다. 내부 쿼리가 외부 쿼리의 값을 참조하기 때문에, 레코드마다 쿼리가 반복 실행되는 구조다.
복잡하지만 조건이 정교한 데이터를 조회할 수 있다.
🎯 서브쿼리 vs JOIN – 어떤 상황에서 쓰는 것이 좋을까?
- JOIN은 두 테이블을 나란히 붙여서 결과를 펼치는 방식
- 서브쿼리는 내부에서 결과를 계산해 조건이나 컬럼으로 사용하는 방식
JOIN은 대량 데이터 연결에 효과적이고, 서브쿼리는 동적인 조건, 비교, 필터링에 적합하다. 상황에 맞게 선택하는 것이 중요하다.
📘 공식 문서 참고 링크
- MySQL Subqueries: https://dev.mysql.com/doc/refman/8.0/en/subqueries.html
'DB' 카테고리의 다른 글
[MySQL] JSON 컬럼 SELECT 조회 완벽 가이드 (0) | 2025.06.26 |
---|---|
[MySQL] LIKE와 REGEXP 차이부터 고급 패턴 검색까지 완벽 정리 (0) | 2025.06.26 |
[MySQL] IS NULL과 IS NOT NULL 완전 정복! 조건절로 놓치지 말아야 할 핵심 포인트 (2) | 2025.06.26 |
[MySQL] SELECT 문에서 EXISTS와 IN 조건절 (1) | 2025.06.26 |
[MySQL] SELECT JOIN 완벽 정리 – INNER JOIN, LEFT JOIN, RIGHT JOIN 차이와 실전 예제 (0) | 2025.06.25 |
[MySQL] SELECT + DATE_FORMAT / NOW() 함수 완벽 정리(날짜포맷, 현재시간) (0) | 2025.06.25 |
[MySQL] SELECT CASE / IF 조건 분기 (쿼리 조건문 활용) (0) | 2025.06.25 |
[MySQL] SELECT + COUNT, SUM, AVG, MAX, MIN 집계 함수 완전 정복 (0) | 2025.06.25 |