본문으로 건너뛰기
SQLD 준비실
이론 전체 목차 열기 14 / 32

SQL 기본 및 활용 · SQL 활용 입문 14 / 32

서브쿼리, 집합 연산자, 뷰

서브쿼리의 위치와 반환 건수, IN·ANY·ALL·EXISTS, UNION 계열 집합 연산자와 뷰의 장점을 시험 기준으로 정리합니다.

출제 빈도 ★★★★★ 관련 문제 12개 | INEXISTSUNIONMINUSVIEW

서브쿼리란

서브쿼리는 SQL 안에 들어 있는 또 다른 SQL입니다. 바깥 쿼리가 메인 쿼리이고, 안쪽 쿼리가 서브쿼리입니다.

SELECT ename, sal
FROM emp
WHERE sal > (
  SELECT AVG(sal)
  FROM emp
);

위 쿼리는 전체 평균 급여보다 급여가 높은 사원을 찾습니다. 서브쿼리가 먼저 평균을 구하고, 메인 쿼리가 그 값을 조건에 사용합니다.

비연관과 연관 서브쿼리

비연관 서브쿼리 (Non-correlated)

  • 메인 쿼리의 열을 참조하지 않음
  • 안쪽 쿼리만 따로 실행 가능
  • 한 번 실행 후 결과 재사용
  • 대개 성능에 유리

연관 서브쿼리 (Correlated)

  • 메인 쿼리의 열을 참조함
  • 안쪽만 따로 실행 불가
  • 바깥 행마다 안쪽이 재평가될 수 있음 (스칼라 캐싱으로 최적화)
  • EXISTS와 자주 결합
SELECT e.ename, e.sal, e.deptno
FROM emp e
WHERE e.sal > (
  SELECT AVG(x.sal)
  FROM emp x
  WHERE x.deptno = e.deptno
);

이 쿼리는 “자기 부서 평균보다 급여가 높은 사원”을 찾습니다. 서브쿼리 안의 e.deptno가 메인 쿼리를 참조하므로 연관 서브쿼리입니다.

반환 건수에 맞는 연산자

서브쿼리 문제는 결과가 몇 행인지 판단하면 절반은 풀립니다.

서브쿼리 결과사용할 수 있는 연산자
단일 행=, >, <, >=, <=, <>평균보다 큰 급여
다중 행IN, ANY, ALL, EXISTS여러 부서 중 하나
다중 컬럼(col1, col2) IN (...)팀별 최솟값 같은 복합 조건

단일 행 연산자에 여러 행이 반환되면 오류가 발생합니다. 반대로 여러 행이 나올 수 있으면 IN, ANY, ALL, EXISTS를 고려합니다.

IN, ANY, ALL, EXISTS

연산자의미초보자용 해석
IN목록 중 하나와 같음후보 중 하나면 통과
= ANY결과 중 하나라도 만족 (= IN)최소 하나만 이기면 통과
< ANY어떤 값보다 작은 것최댓값보다 작으면 통과
> ALL모든 값보다 큼 (= > MAX)전원을 이겨야 통과
< ALL모든 값보다 작음 (= < MIN)전원에게 져야 통과
EXISTS조건을 만족하는 행 존재값보다 존재 여부가 중요
SELECT d.deptno, d.dname
FROM dept d
WHERE EXISTS (
  SELECT 1
  FROM emp e
  WHERE e.deptno = d.deptno
);

EXISTS는 서브쿼리가 어떤 값을 반환하는지보다 “행이 존재하는가”가 핵심입니다. 그래서 SELECT 1처럼 의미 없는 상수를 써도 됩니다.

서브쿼리 위치별 이름

위치이름조건
SELECT스칼라 서브쿼리한 행·한 컬럼만 반환. 2건 이상이면 오류
FROM인라인 뷰서브쿼리 결과를 테이블처럼 사용
WHERE중첩 서브쿼리비교·존재 조건
HAVING그룹 조건 서브쿼리집계 결과 비교

집합 연산자

집합 연산자는 두 SELECT 결과를 위아래로 결합합니다. 조인이 좌우로 컬럼을 붙이는 것과 다릅니다.

연산자결과중복 처리정렬
UNION합집합중복 제거내부 정렬 발생 (비용↑)
UNION ALL합집합중복 유지정렬 없음 (빠름)
INTERSECT교집합중복 제거중복 제거 목적 정렬
EXCEPT / MINUS차집합앞 결과에서 뒤 결과 제거내부 정렬
SELECT deptno FROM emp
UNION
SELECT deptno FROM dept;

집합 연산자를 쓰려면 각 SELECT컬럼 개수대응되는 데이터 타입이 맞아야 합니다. 컬럼 이름은 일치할 필요 없고, 결과 헤더는 첫 번째 SELECT를 따릅니다.

ORDER BY가장 마지막 SELECT 뒤에 한 번만 쓸 수 있습니다.

뷰는 자주 쓰는 SELECT에 이름을 붙여 놓은 가상 테이블입니다. 실제 데이터를 별도로 복사하는 것이 아니라, 조회할 때 정의된 SQL을 재실행합니다.

CREATE VIEW v_emp_dept AS
SELECT e.empno, e.ename, d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno;

뷰의 장점은 세 가지로 정리할 수 있습니다.

  • 편의성: 복잡한 SQL을 단순한 이름으로 사용
  • 보안성: 필요한 컬럼만 공개해 민감 정보 차단
  • 독립성: 원본 테이블 구조가 바뀌어도 사용자 쿼리 영향 최소화

서브쿼리는 결과 건수에 맞는 연산자를 고르고, 집합 연산자는 SELECT 결과를 세로로 합칩니다.