
(릴레이션)
학생(학생번호, 이름)
과목(과목번호, 과목명)
수강(학생번호, 과목번호)
SELECT 학생번호, 이름
FROM 학생
WHERE ( 가 )
( SELECT 과목번호 FROM 과목
WHERE ( 나 )
( SELECT 수강.과목번호
FROM 수강
WHERE 수강.과목번호 = 과목.과목번호
AND 수강.학생번호 = 학생.학생번호 ) );
| 번호 | 가 | 나 |
| ① | EXISTS | EXISTS |
| ② | NOT EXISTS | EXISTS |
| ③ | EXISTS | NOT EXISTS |
| ④ | NOT EXISTS | NOT EXISTS |
1. 쿼리 구조 분석
- 가장 안쪽 서브쿼리: 특정 학생(학생.학생번호)이 특정 과목(과목.과목번호)을 수강하고 있는지(수강 테이블에 데이터가 있는지) 확인합니다.
- 중간 서브쿼리 (나 조건): 과목 테이블의 모든 과목을 대상으로, 해당 학생이 그 과목을 수강하는지(또는 수강하지 않는지)를 판별하여 조건에 맞는 과목들의 집합을 반환합니다.
- 가장 바깥쪽 메인 쿼리 (가 조건): 학생 테이블의 모든 학생을 대상으로, 중간 서브쿼리에서 반환된 과목 집합이 존재하는지(또는 존재하지 않는지)를 판별하여 최종적으로 학생을 선택합니다.
2. 각 보기별 결과 해석
① 가: EXISTS, 나: EXISTS
- 해석: 나. EXISTS: 해당 학생이 수강하고 있는 과목들을 찾습니다.
- 가. EXISTS: 그렇게 찾은 '수강 중인 과목'이 하나라도 존재하는 학생을 선택합니다.
- 결과: 적어도 한 과목 이상 수강하는 학생의 학생번호와 이름을 조회합니다.
② 가: NOT EXISTS, 나: EXISTS
- 해석: 나. EXISTS: 해당 학생이 수강하고 있는 과목들을 찾습니다.
- 가. NOT EXISTS: 그렇게 찾은 '수강 중인 과목'이 하나도 없는 학생을 선택합니다.
- 결과: 아무 과목도 수강하지 않는 학생의 학생번호와 이름을 조회합니다.
③ 가: EXISTS, 나: NOT EXISTS
- 해석: 나. NOT EXISTS: 해당 학생이 수강하지 않는 과목들을 찾습니다.
- 가. EXISTS: 그렇게 찾은 '수강하지 않는 과목'이 하나라도 존재하는 학생을 선택합니다.
- 결과: 수강하지 않는 과목이 하나라도 있는 학생 (즉, 개설된 모든 과목을 전부 수강하지는 않은 학생)의 학생번호와 이름을 조회합니다.
④ 가: NOT EXISTS, 나: NOT EXISTS
- 해석: 나. NOT EXISTS: 해당 학생이 수강하지 않는 과목들을 찾습니다.
- 가. NOT EXISTS: 그렇게 찾은 '수강하지 않는 과목'이 단 하나도 없는 학생을 선택합니다. (이중 부정)
- 결과: 수강하지 않은 과목이 없으므로, 모든 과목을 빠짐없이 수강하는 학생의 학생번호와 이름을 조회합니다. (관계대수에서 릴레이션 나누기(Division) 연산과 동일한 결과입니다.)
'DB' 카테고리의 다른 글
| [인덱싱] 비트맵 조인 인덱스(Bitmap Join Index) (0) | 2026.02.14 |
|---|---|
| [인덱싱] 클러스터 인덱스와 희소 인덱스 (0) | 2026.02.14 |
| [조인] 조인을 상관서브쿼리로 표현 (0) | 2026.02.14 |
| 인덱스를 사용할 수 없는 경우 (0) | 2026.02.13 |
| [뷰] 갱신제약 (0) | 2026.02.13 |