EXISTS는 행의 존재, ANY는 비교가 하나 이상 참인지, ALL은 모든 비교가 참인지 묻는다. NULL과 빈 집합도 따로 살핀다.
상관 서브쿼리는 바깥 행의 값을 안쪽에서 참조한다. 아래 NOT EXISTS는 각 책번호와 연결된 대출 행이 없는 책 3·4번을 반환한다. 실제 실행 횟수나 물리 처리 방식은 옵티마이저에 따라 달라질 수 있다.
170 > ANY(120, 200)는 참이고 170 > ALL(120, 200)는 거짓이다. 비교 대상이 빈 집합이면 ANY는 거짓, ALL은 참이다. NULL 때문에 참·거짓이 확정되지 않을 수도 있다.
NOT IN의 비교 집합에 NULL이 들어 있고 일치하는 값도 없다면 결과가 참이 아니라 미정일 수 있다. 단순히 NOT EXISTS와 같은 문법이라고 바꾸지 말고 NULL 가능성과 상관 조건을 먼저 확인한다.
- 01 →
바깥 행의 값
- 02 →
안쪽 결과
- 03 →
존재·비교 조건
- 04
NULL·빈 집합
같은 상황에서 비교하기
| 개념 | 기준 | 확인할 점 |
|---|---|---|
| EXISTS | 한 행이라도 존재 | 값보다 행 존재를 본다 |
| ANY | 하나 이상 비교 참 | 빈 집합은 거짓 |
| ALL | 모든 비교 참 | 빈 집합은 참 |
| NOT IN | 모두와 다름 | NULL이 끼면 미정 가능 |
도서관 예제로 따라가기
SELECT b.book_id
FROM books b
WHERE NOT EXISTS (
SELECT 1 FROM loans l
WHERE l.book_id = b.book_id
)
ORDER BY b.book_id;| book_id |
|---|
| 3 |
| 4 |
안쪽의 SELECT 1은 값을 합산하는 것이 아니라 행의 존재를 확인하는 표현이다.
공통 예제 데이터 보기
| book_id | title | shelf_code | pages |
|---|---|---|---|
| 1 | SQL 입문 | DB | 120 |
| 2 | 설계 노트 | SW | 200 |
| 3 | 관계 모델 | DB | NULL |
| 4 | 분산 읽기 | NULL | 160 |
| loan_id | book_id |
|---|---|
| 11 | 1 |
| 12 | 1 |
| 13 | 2 |
내 말로 설명해 보기
비교 대상이 하나도 없을 때 >ALL과 >ANY의 결과는?
설명 예시 확인
ALL은 참이고 ANY는 거짓이다. NULL 원소가 있는 집합과 원소 자체가 없는 빈 집합은 구분한다.