서브쿼리
평균 급여보다 높은 급여를 받는 사람은 누구인가요?
→ 서브쿼리를 활용할 수 있습니다
메인 쿼리: 어떤 직원들이 평균 급여보다 높은 급여를 받고 있나요?
서브쿼리: 평균 급여는 얼마인가요?
다른 쿼리 내에 중첩된 SFW 표현식
- 더 큰 쿼리 내에 중첩된 SQL을 포함합니다
- 외부 쿼리 - 내부 쿼리
여러 절에서 사용할 수 있습니다
WHERE 절
- 스칼라 서브쿼리
단일 상수를 반환하는 서브쿼리
WHERE 절에서 서브쿼리를 상수처럼 사용하여 모든 연산자를 사용할 수 있습니다
- 집합 멤버십
집합 멤버십에는 IN, NOT IN, EXISTS, NOT EXISTS 연산자를 사용합니다
값이 서브쿼리의 결과 관계에 있는지 확인하는 조건
- 집합 비교
집합 비교에는 ANY (SOME), ALL을 사용합니다
서브쿼리의 결과 관계의 임의 값 또는 모든 값과의 비교
- 빈 관계 테스트
EXISTS는 인수 서브쿼리가 비어있지 않으면 참을 반환합니다
NOT EXISTS는 인수 서브쿼리가 비어있으면 참을 반환합니다
상관 서브쿼리 Correlated Subquery:
외부 쿼리의 속성에 대한 참조를 포함하는 서브쿼리로, 외부 쿼리의 각 행에 대해 한 번씩 평가됩니다(for 루프와 같이) → 종종 비효율적입니다
Q. 모든 지점에 계좌를 가지고 있는 고객의 customerID를 찾으세요
X: 모든 지점 이름 목록
Y: 고객이 계좌를 가지고 있는 지점 이름 목록
→ X-Y가 공집합이라면 해당 고객은 모든 지점에 계좌를 가지고 있습니다
SELECT C.customerID
FROM Cusomer C
WHERE NOT EXISTS((SELECT B.branchName FROM Branch B)
EXCEPT
(SELECT A.branchName
FROM Account A, Owns O
WHERE O.customerID = C.customerID
AND O.accNumber = A.accNumber))
- 중복 튜플 부재 테스트
→ 중복이 없으면 True를 반환합니다
2017년에 최대 한 번만 제공된 모든 과정 찾기
하지만 PostgreSQL에는 UNIQUE 술어가 없습니다
UNIQUE는 서브쿼리의 결과에 중복 튜플이 있는지 테스트합니다
Q. 그렇다면 이를 어떻게 구현할 수 있을까요?
SELECT T.course_id
FROM course AS T
where UNIQUE(
Select R.course_id
FROM section AS R
WHERE T.course_id=R.course_id
AND R.year=2017);
SELECT T.course_id
FROM course AS T JOIN section AS R ON T.course_id = R.course_id
WHERE R.year = 2017
GROUP BY T.course_id
HAVING COUNT(R.section_id) <= 1;
SELECT 절
SELECT 절에서 스칼라 서브쿼리를 사용할 수 있습니다
예:
각 학과와 함께 해당 학과의 강사 수를 찾으세요
SELECT dept_name (SELECT count(*)
FROM instructor
WHERE department.dept_name=instructor.dept_name)
as num_instructors
FROM department;
일부 쿼리는 최상위 쿼리에 FROM 절이 필요 없이 FROM 절을 포함하는 서브쿼리를 가질 수 있습니다
→ Oracle과 같은 일부 시스템에서는 불법일 수 있습니다
FROM 절
서브쿼리의 결과 관계를 FROM 절에서 사용할 수 있습니다
Q. 총 잔액이 0인 고객은 누구인가요?
- 각 고객의 잔액 합계 → 서브쿼리
- 그 중에서 0인 것을 찾기
SELECT firstName, lastName, sumBalance
FROM (SELECT firstName, lastName, sum(balance) as sumBalance
FROM Customer C, Account A, Owns O
WHERE C.customerID=O.cusomerID
AND O.accNumber = A.accNumber
GROUP BY C.customerID) T
WHERE T.sumBalance = 0
하지만 중첩 쿼리를 피하기 위해 -> 비효율적
SELECT firstName, lastName, sum(balance) as sumBalance
FROM Customer C, Account A, Owns O
WHERE C.customerID=O.cusomerID AND O.accNumber = A.accNumber
GROUP BY C.customerID
HAVING T.sumBalance = 0
WITH 절
임시 관계를 정의하며, WITH 절이 발생하는 쿼리에서만 사용 가능합니다
예:
최대 예산을 가진 모든 부서를 찾으세요
- 최대 예산 찾기 → WITH 절이 있는 서브쿼리
- 예산이 최대 예산과 같은 부서 찾기
WITH max_budget (value) AS #WITH {관계 이름} ({속성 이름})
SELECT max(budget)
FROM department)
SELECT department.dept_name
FROM department, max_budget
WHERE department.budget = max_budget.value;
'컴퓨터공학 > 데이터베이스 DB' 카테고리의 다른 글
전공생의 데이터베이스 수업 수강 전 SQLD 합격 후기 (2) | 2024.11.07 |
---|---|
Correlated Subquery 상관 서브쿼리 (2) | 2024.10.22 |
외부 조인과 내부 조인 Inner Join and Outer Join (2) | 2024.10.20 |
기초 SQL문 정리 SFW, HAVING, GROUP BY ... (8) | 2024.10.19 |
데이터베이스 SQL DDL과 DML (5) | 2024.10.18 |