[DB] DB05 - 요약
DB05 - More SQL
중첩 서브쿼리
- 의미
: 다른 서브쿼리의 결과를 사용하는 쿼리로, 주 쿼리 안에 포함된 서브쿼리이다.
- 가능한 절의 종류
SELECT A1, A2, ..., An
FROM r1, r2, ..., rm
WHERE P
(1) FROM 절에서는 ri라는 테이블이 유효한 서브쿼리로 대체될 수 있다.
(2) WHERE 절에서는 조건 P가 속성 B와 서브쿼리를 이용한 <연산>의 형태로 표현될 수 있다.
(3) SELECT 절에서는 Ai가 하나의 값을 반환하는 서브쿼리로 대체될 수 있으며, 이를 스칼라 서브쿼리라고 한다.
WITH Clause
- WITH 절은 임시 관계를 정의하는 방법을 제공한다.
- 관계는 WITH 절이 발생하는 쿼리에서만 사용 가능하다.
Scalar Subquery
1. 스칼라 서브쿼리는 단일 값이 예상되는 곳에서 사용된다.
- 스칼라 서브쿼리(Scalar Subquery)는 단일 값(하나의 튜플과 하나의 컬럼)을 반환하는 서브쿼리이다.
- 서브쿼리가 둘 이상의 결과 튜플을 반환하면 런타임 오류가 발생한다.
- 스칼라 서브쿼리는 WHERE 절, SELECT 절 등 단일 값이 필요한 위치에서 사용된다.
SOME
1. SOME의 의미
SOME은 비교 연산자와 함께 사용되어, **"어떤 값이라도 조건을 만족하면 참"**이라는 의미를 가진다.
예를 들어, 5 < SOME [0,5,6]
2. SOME 연산자 예시
- 5 < SOME [0,5,6] → 리스트에서 5보다 큰 값(6)이 있으므로 참 (true)
- 5 < SOME [0,5] → 리스트에서 5보다 큰 값이 없으므로 거짓 (false)
- 5 = SOME [0,5] → 리스트에서 5와 같은 값이 있으므로 참 (true)
- 5 ≠ SOME [0,5] → 리스트에서 5와 다른 값(0)이 하나라도 있으므로 참 (true)
3. 중요한 특징
- = SOME은 IN과 동일 → "같은 값이 존재하냐?"
- 예: 5 = SOME [0,5,6] → 5 IN [0,5,6]과 동일
- ≠ SOME은 NOT IN과 다름 → "다른 값이 하나라도 있으면 참"
- 예: 5 ≠ SOME [0,5] → 5와 다른 값(0)이 존재하므로 참 (하지만 5 NOT IN [0,5]는 거짓)
4. 핵심 요약
SOME은 비교 연산과 함께 사용하여 **"리스트(또는 서브쿼리) 안에서 조건을 만족하는 값이 하나라도 있으면 참"**이라는 개념을 의미한다.
ALL
1. ALL의 의미
ALL은 비교 연산자와 함께 사용되어, "모든 값이 조건을 만족해야 참"이라는 의미를 가진다.
예를 들어, 5 < ALL [0,5,6]
2. ALL 연산자 예시
- 5 < ALL [0,5,6] → 5보다 작은 값이 아닌 6이 있기 때문에 거짓 (false)
- 5 < ALL [6,10] → 모든 값(6,10)이 5보다 크므로 참 (true)
- 5 = ALL [4,5] → 모든 값이 5와 같아야 하지만 4가 있어서 거짓 (false)
- 5 ≠ ALL [4,6] → 모든 값(4,6)이 5와 다르므로 참 (true)
3. 중요한 특징
- ≠ ALL은 NOT IN과 동일 → "모두와 다르다"
- 예: 5 ≠ ALL [4,6] → 5 NOT IN [4,6]과 동일
- = ALL은 IN과 다름 → "모두와 같다"는 의미는 IN과 다르다
- 예: 5 = ALL [5,5]이면 참이지만, 5 = ALL [4,5]는 거짓
4. 핵심 요약
ALL은 "비교하는 모든 값이 조건을 만족해야 참"이라는 개념을 의미하며, SOME과 반대되는 개념이다.
빈 관계(Empty Relations) 테스트
1. EXISTS 연산자의 의미
- EXISTS는 "서브쿼리 결과가 비어 있지 않으면 참(true)"이 된다.
- 즉, EXISTS r는 r ≠ Ø와 동치이다.
- 반대로, NOT EXISTS r는 r = Ø와 동치이다.
예를 들어,
EXCEPT 사용 (MySQL 미지원)
- MySQL은 EXCEPT 연산자를 지원하지 않음.
- 다른 DBMS에서는 아래처럼 사용 가능.
SELECT DISTINCT S.ID, S.name
FROM student AS S
WHERE NOT EXISTS (
(
SELECT course_id
FROM course
WHERE dept_name = 'Music'
)
EXCEPT
(
SELECT T.course_id
FROM takes AS T
WHERE S.ID = T.ID
)
);
→ 학생이 음악 부서의 모든 과목을 수강했는지 확인하는 방법
Test for Absence of Duplicate Tuples (중복 튜플이 없는지 테스트하기)
- UNIQUE 구성은 서브쿼리가 결과에 중복 튜플이 있는지 테스트한다.
- UNIQUE는 주어진 서브쿼리에 중복이 없으면 "true"로 평가된다.
- MySQL은 UNIQUE 테스트를 지원하지 않는다(UNIQUE는 MySQL에서 제약 조건 지정자이다).
- 2017년에 최대 한 번 개설된 모든 과목을 찾는다.
SELECT T.course_id
FROM course AS T
WHERE UNIQUE (
SELECT R.course_id
FROM teaches AS R
WHERE T.course_id = R.course_id AND R.year = 2017
);
UNIQUE는 MySQL에서 서브쿼리에 사용할 수 있는 연산자가 아니다.