데이터베이스 연구실.log

EXISTS와 NOT EXISTS

서브쿼리 결과의 존재 여부만 확인하는 EXISTS와 NOT EXISTS의 사용법과, NOT IN을 NOT EXISTS로 바꾸는 예, 업무형 실습 문제

EXISTSNOT EXISTS상관 서브쿼리존재 여부

#핵심 요약

WHERE EXISTS (SELECT 1 FROM emp e WHERE e.deptno = d.deptno)는 사원 테이블에 그 부서번호가 하나라도 있는 부서만 고름

메인쿼리의 값(d.deptno)을 서브쿼리에 넘겨 존재하는지 찾고, 찾으면 거기서 멈춤

NOT EXISTS는 존재하지 않는 행을 고름
실습에서는 NOT IN으로 쓴 "직속 부하가 없는 사원"을 NOT EXISTS로 바꾸게 했음

#개념과 동작 원리

서브쿼리가 한 단계 이상 위 문장의 테이블 컬럼을 참조하면 상관 서브쿼리(correlated subquery)임
상관 서브쿼리는 개념상 부모 문장이 처리하는 행마다 한 번씩 평가됨
EXISTS 예제의 e.deptno = d.deptno가 바깥 dept의 컬럼을 참조하는 상관 조건임

옵티마이저는 같은 의미의 조인 등으로 상관 서브쿼리를 변환할 수 있음

#주요 용어와 구성 요소

구문 의미
EXISTS 서브쿼리가 하나 이상의 행을 반환하면 참임
NOT EXISTS 서브쿼리가 행을 반환하지 않으면 참임
상관 조건 안쪽 행을 바깥 행과 연결하며 빠뜨리면 전체 집합의 존재만 검사하게 됨

#필수 명령어 또는 SQL

항목 실행 조건
작업 대상 dept와 emp의 부서 대응, emp의 직속 부하 존재 여부
필요 권한 참조하는 모든 테이블에 대한 조회 권한이 있는 계정
바꿀 입력값 바깥, 안쪽 별칭, 연결 키와 업무 필터
결과 해석 업무형 연습 문제 답과 실제 행 목록은 확인 불가
SQL Developer 또는 SQL*Plus조회만 함
SELECT deptno
  FROM dept d
 WHERE EXISTS (SELECT 1
                 FROM emp e
                WHERE e.deptno = d.deptno);

결과 해석:

실습 테이블: 통신사 요금표 telecom_table(통신사, 요금, 건수)에 KT, LG, SKT와 알뜰 요금제 세 개를 넣었음
문제는 "emp19에 존재하는(존재하지 않는) 통신사만 출력"임(답 확인 불가)
emp19의 통신사 값은 대소문자가 섞여 있어 비교 전에 맞춰야 함(조건별 값 변환)

#NOT IN을 NOT EXISTS로

연습 문제의 NOT IN 문장:

SQL Developer 또는 SQL*Plus조회만 함
SELECT ename
  FROM emp
 WHERE empno NOT IN (SELECT mgr
                       FROM emp
                      WHERE mgr IS NOT NULL);

결과 해석:

같은 뜻을 NOT EXISTS로 쓰면 다음과 같음(답 확인 불가)

SQL Developer 또는 SQL*Plus조회만 함
SELECT e.ename
  FROM emp e
 WHERE NOT EXISTS (SELECT 1
                     FROM emp m
                    WHERE m.mgr = e.empno);

결과 해석:

NOT EXISTS는 서브쿼리 행이 있는지만 보므로, NOT IN처럼 서브쿼리 결과의 NULL 때문에 전체가 비는 문제가 없음(NOT IN과 NULL)

#업무형 실습

실습에서는 쇼핑몰 고객, 주문, 쿠폰, 상품, 주문상세 테이블을 만들고 두 문제를 냈음

  1. EXISTS: 2024년 5월에 상태가 PAID인 주문이 한 건이라도 있는 고객의 ID, 이름, 등급
  2. NOT EXISTS: 쿠폰을 한 번도 받지 않은 고객의 ID, 이름, 가입일

실습의 테이블 삭제 스크립트에는 DROP TABLE order_items가 두 번 있음

#구문과 옵션 설명

서브쿼리 안의 열 참조는 별칭으로 한정해 안쪽, 바깥쪽 열의 혼동을 피함
바깥 테이블에 같은 키가 여러 행이면 EXISTS는 그 행들을 자동으로 중복 제거하지 않음

#사용 조건과 주의사항

NOT IN을 NOT EXISTS로 바꿀 때는 비교하는 바깥 키의 NULL 가능성도 확인해야 함
본문의 두 형태를 같은 뜻으로 보는 설명은 바깥 empno가 NULL이 아닌 키인 조건임

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기