현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

서브쿼리: Single·Multi·Correlated

단일행·다중행·상관 서브쿼리를 반환 행 수와 외부 행 의존성으로 구분한다.

예상 읽기 6

핵심 요약

단일행·다중행·상관 서브쿼리를 반환 행 수와 외부 행 의존성으로 구분한다.

핵심 질문

  1. 서브쿼리: Single·Multi·Correlated에서 반드시 구분해야 할 개념과 결과 규칙은 무엇인가?
  2. 0건·1건·여러 건과 NULL·동점·중복 데이터에서 결과가 어떻게 달라지는가?
  3. 비슷해 보이는 문법과 결과가 같아지는 조건, 달라지는 조건은 무엇인가?
  4. 작은 샘플 데이터를 이용해 결과를 실수 없이 예측하는 순서는 무엇인가?

학습 목표

  • 서브쿼리 반환 건수에 맞는 연산자를 선택한다.
  • 상관 서브쿼리가 외부 쿼리의 행을 참조하는 방식을 설명한다.

개념 지도

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
외부 행 단위 → 서브쿼리 반환 행 수 → 연산자 규칙 → NULL·상관 여부 확인

핵심 내용

서브쿼리는 다른 SQL 안에 포함된 질의다. 위치에 따라 스칼라 서브쿼리, 인라인 뷰, WHERE 서브쿼리 등으로 사용된다.

단일행 서브쿼리는 0 또는 1행을 기대하며 =, <, > 같은 단일행 연산자를 쓴다. 여러 행을 반환할 수 있으면 IN, ANY, ALL, EXISTS 같은 연산자가 필요하다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT e.empno, e.sal
FROM emp e
WHERE e.sal > (
  SELECT AVG(sal) FROM emp
);

상관 서브쿼리는 내부 쿼리가 외부 행의 값을 참조한다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT e.empno
FROM emp e
WHERE e.sal > (
  SELECT AVG(x.sal) FROM emp x WHERE x.deptno = e.deptno
);

상관 서브쿼리는 외부 Query의 현재 행 값을 참조하며, 각 외부 행에 대해 조건의 참·거짓을 판단하는 형태로 해석한다.

흔한 오해와 주의점

  • = 뒤 서브쿼리가 두 행 이상 반환하면 단일행 서브쿼리 오류가 난다.
  • 스칼라 서브쿼리가 0행이면 NULL, 두 행 이상이면 오류다.
  • 상관 서브쿼리의 논리적 의미와 실제 반복 실행 횟수를 동일시하지 않는다.

문항 풀이 보강: 다중행 비교와 그룹별 최신 행

표현의미
x > ANY (subquery)결과 중 하나보다 크면 됨, 사실상 최솟값보다 큼
x > ALL (subquery)모든 결과보다 커야 함, 사실상 최댓값보다 큼
x IN (subquery)결과 중 같은 값이 하나라도 있음
EXISTS (subquery)조건을 만족하는 행이 하나라도 존재

서브쿼리가 빈 집합일 때 ANY와 ALL의 논리 결과도 구분한다. NULL이 섞이면 3값 논리를 함께 적용한다.

그룹별 최초·최신 한 행

광고매체별 최초 광고처럼 “그룹별 한 행”을 구할 때 단순 MIN(날짜)만 선택하면 같은 행의 광고명을 함께 가져오지 못할 수 있다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT *
FROM (
  SELECT p.*,
         ROW_NUMBER() OVER (
           PARTITION BY media_id
           ORDER BY start_dt, post_id
         ) rn
  FROM ad_post p
)
WHERE rn = 1;

상관 서브쿼리로 현재 행보다 더 빠른 행이 없는지 검사하거나, 집계 결과를 원본과 다시 조인하는 방법도 있다. 동점 처리 기준까지 명시해야 결과가 결정적이다.

스칼라 서브쿼리

SELECT 목록의 스칼라 서브쿼리는 0행이면 NULL, 정확히 1행이면 그 값, 2행 이상이면 오류다. COUNT(*) 집계는 입력이 없어도 0 한 행을 반환하므로 부양가족 수 같은 계산에 사용할 수 있다.

문제에 적용하는 순서

  1. 서브쿼리가 몇 행을 반환할 수 있는지 판단한다.
  2. 외부 행을 참조하는 상관 조건을 표시한다.
  3. 단일행 연산자와 다중행 연산자가 맞는지 본다.
  4. 그룹별 한 행이면 동점과 연결 컬럼의 일관성을 확인한다.

반환 행 수와 연산자 맞추기

서브쿼리 결과사용할 수 있는 대표 연산자다건일 때
Scalar 0·1행=, <, >2행 이상이면 ORA-01427
Multi RowIN, ANY, ALL, EXISTS집합 규칙으로 평가
Correlated외부 행마다 논리적으로 평가Unnesting·Cache 가능
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT ename
FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

집계 Scalar Subquery는 입력이 0행이어도 AVG 결과 한 행(NULL)을 반환한다는 점과, 일반 Scalar Subquery의 0행→NULL 규칙을 구분한다.

ANY와 ALL

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
x > ANY(10,20,30)  → 최소값 10보다 크면 참 가능
x > ALL(10,20,30)  → 최대값 30보다 커야 참

빈 집합과 NULL이 포함되면 결과가 달라지므로 논리식을 직접 계산한다.

상관 서브쿼리

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT d.deptno
FROM dept d
WHERE EXISTS (
  SELECT 1 FROM emp e
  WHERE e.deptno = d.deptno
  AND e.status = 'ACTIVE'
);

IN과 EXISTS는 NULL과 중복의 영향까지 같을 때에만 서로 바꿔 쓸 수 있다. 문법 모양만 보고 두 표현이 항상 같은 결과라고 판단하지 않는다.

변환 주의

Scalar를 Join으로 바꾸면 오른쪽 중복 때문에 외부 행 수가 늘 수 있다. 0건→NULL, 다건→오류라는 원래 의미를 보존하는지 먼저 확인한다.


결과를 검증하는 순서

  1. 각 Query Block이 만드는 한 행의 의미를 먼저 적습니다.
  2. 조건을 적용하기 전 원본 행과 적용 후 남는 행을 작은 표로 그립니다.
  3. NULL 비교가 TRUE, FALSE, UNKNOWN 중 무엇인지 구분합니다.
  4. 중복 제거, 그룹화, 정렬과 행 제한이 적용되는 순서를 확인합니다.
  5. 데이터가 0건·1건·여러 건일 때도 같은 규칙이 성립하는지 검증합니다.

실무와 시험에서 함께 확인할 항목

  • ORDER BY가 없다면 결과 순서를 가정하지 않습니다.
  • 문자열·숫자·날짜 비교에서는 데이터 타입과 명시적 형변환을 확인합니다.
  • 같은 결과처럼 보이는 SQL도 NULL과 중복이 있을 때 달라질 수 있습니다.
  • 문법을 외우기 전에 샘플 데이터 3~5행으로 결과를 직접 계산합니다.

마지막 점검

  • 작성 순서가 아니라 SQL의 논리적 처리 순서로 결과를 계산합니다.
  • NULL을 0이나 빈 값과 같은 것으로 취급하지 않습니다.
  • ORDER BY가 없는 결과 순서와 DISTINCT 없는 중복 제거를 가정하지 않습니다.
  • 비슷한 문법은 0건·다건·NULL 데이터를 넣어 결과가 정말 같은지 확인합니다.

복습 문제

  1. 부서별 평균보다 급여가 높은 사원을 찾는 서브쿼리는 왜 상관 서브쿼리인가?
  2. 다중행 결과에 =를 사용하면 어떻게 되는가?
  3. 샘플 데이터 3행으로 결과를 직접 계산할 수 있는가?
  4. NULL이 포함될 때 결과가 달라지는 지점은 어디인가?