T'SPACE

다채로운 에디터들의 이야기

컴퓨터공학/데이터베이스 DB

SQL 서브쿼리 Subquery

Tonny Kang 2024. 10. 21. 08:51
반응형

서브쿼리


평균 급여보다 높은 급여를 받는 사람은 누구인가요?

→ 서브쿼리를 활용할 수 있습니다

 

메인 쿼리: 어떤 직원들이 평균 급여보다 높은 급여를 받고 있나요?

서브쿼리: 평균 급여는 얼마인가요?

다른 쿼리 내에 중첩된 SFW 표현식

  • 더 큰 쿼리 내에 중첩된 SQL을 포함합니다

  • 외부 쿼리 - 내부 쿼리

여러 절에서 사용할 수 있습니다

반응형

WHERE 절


  1. 스칼라 서브쿼리

단일 상수를 반환하는 서브쿼리

WHERE 절에서 서브쿼리를 상수처럼 사용하여 모든 연산자를 사용할 수 있습니다

  1. 집합 멤버십

집합 멤버십에는 IN, NOT IN, EXISTS, NOT EXISTS 연산자를 사용합니다

값이 서브쿼리의 결과 관계에 있는지 확인하는 조건

  1. 집합 비교

집합 비교에는 ANY (SOME), ALL을 사용합니다

서브쿼리의 결과 관계의 임의 값 또는 모든 값과의 비교

  1. 빈 관계 테스트

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))
  1. 중복 튜플 부재 테스트

→ 중복이 없으면 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;

 

728x90

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인 고객은 누구인가요?

  1. 각 고객의 잔액 합계 → 서브쿼리
  2. 그 중에서 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 절이 발생하는 쿼리에서만 사용 가능합니다

예:

최대 예산을 가진 모든 부서를 찾으세요

  1. 최대 예산 찾기 → WITH 절이 있는 서브쿼리
  2. 예산이 최대 예산과 같은 부서 찾기
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;
반응형