단일행인지 다중행인지, 메인 쿼리와 연동되는 상관 서브쿼리인지, SELECT에 들어가는 스칼라 서브쿼리인지를 먼저 구분하면 대부분의 오류를 줄일 수 있습니다.
핵심 체크포인트
- 서브쿼리 결과가 한 값인지 여러 값인지 먼저 확인해야 합니다.
- 상관 서브쿼리는 메인 쿼리의 행마다 다시 실행되는 구조를 이해해야 합니다.
- 인라인 뷰는 FROM 절 안의 임시 결과 집합이라고 생각하면 편합니다.
주제별 설명
단일행 서브쿼리
하나의 값만 반환해 `=` 같은 단일 비교 연산자와 함께 쓰는 서브쿼리입니다.
- 결과가 여러 행이 나오면 단일행 비교 연산자에서 오류가 납니다.
- 집계 함수와 함께 자주 등장해 기준값 비교에 많이 쓰입니다.
다중행 서브쿼리
여러 값을 반환하며 `IN`, `ANY`, `ALL` 같은 연산자와 함께 사용하는 서브쿼리입니다.
- `=` 대신 `IN`을 써야 하는 상황인지 먼저 구분하는 것이 핵심입니다.
- 서브쿼리 결과 개수에 따라 비교 연산자가 달라집니다.
상관 서브쿼리
메인 쿼리의 컬럼을 참조하면서 각 행마다 다시 평가되는 서브쿼리입니다.
- 존재 여부 확인, 조건부 비교에서 매우 강력합니다.
- JOIN으로도 풀 수 있지만 논리를 읽기 쉽게 만들 때 장점이 있습니다.
SELECT m.member_id,
m.member_name
FROM members m
WHERE EXISTS (
SELECT 1
FROM payments p
WHERE p.member_id = m.member_id
);스칼라 서브쿼리
SELECT 절에서 하나의 값을 붙일 때 쓰는 서브쿼리입니다.
- 한 행당 하나의 보조 값만 붙일 수 있습니다.
- 건수, 최근일자, 대표값을 붙이는 패턴에서 자주 보입니다.
FROM 절 서브쿼리 (Inline View)
서브쿼리 결과를 FROM 절에서 임시 테이블처럼 다루는 방식입니다.
- 먼저 집계하거나 가공한 결과를 바깥 쿼리에서 다시 정렬, 필터링할 때 유용합니다.
- 복잡한 집계를 단계적으로 나눌 수 있어 가독성이 좋아집니다.
EXISTS / IN / ANY / ALL
서브쿼리 결과를 어떻게 비교할지 정하는 대표 연산자들입니다.
- EXISTS는 존재 여부, IN은 집합 포함, ANY와 ALL은 비교 범위를 나타냅니다.
- 문법보다도 서브쿼리 결과를 어떤 의미로 해석할지 이해하는 것이 중요합니다.
SELECT member_name
FROM members
WHERE member_id IN (
SELECT member_id
FROM payments
WHERE product_id = 4
);실습 흐름 추천
- 집계 결과 하나를 비교하는 단일행 서브쿼리부터 시작합니다.
- 여러 값 비교가 필요하면 IN, ANY, ALL로 연산자를 바꿔봅니다.
- 존재 여부는 EXISTS로 바꿔 결과와 의도를 비교해보면 감이 빨리 잡힙니다.
바로 이어서 해보려면
이론만 읽지 말고 바로 blacksql.sqld.kr에서 실행해보고, 문제 풀이 감각은 www.sqld.kr에서 이어가면 학습 속도가 훨씬 빨라집니다.
자주 묻는 질문
둘 다 가능할 때가 많지만, 존재 여부나 기준값 비교처럼 논리가 분명하면 서브쿼리가 더 읽기 쉬운 경우가 많습니다.
단일행이어야 하는 서브쿼리가 여러 행을 반환했기 때문입니다. 연산자를 IN으로 바꾸거나 서브쿼리 결과를 한 행으로 줄여야 합니다.