서브쿼리

hyekyeong Song·2020년 5월 21일
1

서브쿼리가 위치할 수 있는 곳

  1. SELECT절
  2. FROM절
  3. WHERE절
  4. HAVING절
  5. ORDER BY절
  6. INSERT문의 VALUES절
  7. UPDATE문의 SET절

주의사항
1) 서브쿼리를 사용할 때에는 괄호로 감싸야 한다
2) 서브쿼리 안에서는 ORDER BY를 사용할 수 없다.



동작 방식에 따른 분류

1. 비연관 서브쿼리(Un-Correlated subquery)

: 서브쿼리가 메인쿼리 컬럼을 갖고 있지 않은 형태의 서브쿼리이다.
주로 메인쿼리에 서브쿼리가 실행된 결과를 제공하기 위한 목적으로 사용한다.

2. 연관 서브쿼리(Correlated subquery)

: 서브쿼리가 메인쿼리의 컬럼을 갖고 있는 형태의 서브쿼리이다.
주로 메인쿼리가 먼저 수행되어 읽혀진 데이터를 서브쿼리에서 조건이 맞는지 확인할 때 사용한다.

SELECT T1.C1
       ,T1.C2
       ,T1.C3
  FROM T1 T1
 WHERE (T1.C1, T1.C2) IN (SELECT T2.C1
                                 ,T2.C2
                            FROM T2 T2
                           WHERE T2.C2 = T1.C2
                         );


반환되는 결과에 따른 분류

1. 단일 행 서브쿼리(Single Row subquery)

: 서브쿼리 실행 결과가 항상 1건 이하인 서브쿼리이다.

함께 사용하는 단일행 비교 연산자 : =, <, <=, >, >=, <>

SELECT C1
       ,C2
       ,C3
  FROM T1
 WHERE C1 = (SELECT C1
               FROM T2
              WHERE C2 = 'ABC'
            );

2. 다중 행 서브쿼리(Multi Row subquery)

: 서브쿼리 실행 결과가 여러 건인 서브쿼리이다.

함께 사용하는 다중 행 비교 연산자 : IN, ALL, ANY, SOME, EXISTS

연산자설명
IN서브쿼리 결과의 임의의 값과 동일한 조건
ALL서브쿼리 결과의 모든 값을 만족하는 조건
ANY서브쿼리 결과의 어느 하나의 값이라도 만족하는 조건
EXISTS서브쿼리 결과를 만족하는 값이 존재하는지 확인하는 조건. EXISTS로 검색된 결과가 하나라도 존재하면 메인쿼리 조건절이 참이된다
NOT EXISTS서브쿼리 결과를 만족하는 값이 존재하지 않는지 확인하는 조건. NOT EXISTS로 검색된 결과가 하나도 존재하지 않으면 메인쿼리 조건절이 참이된다
SELECT C1
  FROM T1
 WHERE C1 IN (SELECT C1
                FROM T2
             )
  • 부등호를 이용하는 다중 행 서브쿼리문은 MIN과 MAX 함수로 수정할 수 있다.
ANY or ALL의미같은 표현
컬럼 > ANY가장 작은 값보다 크다컬럼 > MIN
컬럼 < ANY가장 큰 값보다 작다컬럼 < MAX
컬럼 > ALL가장 큰 값보다 크다컬럼 > MAX
컬럼 < ALL가장 작은 값보다 작다컬럼 < MIN

EX. 직책이 'ABC'인 사원들 중 가장 많은 급여를 받는 사람보다 급여가 작은 사원 검색

SELECT EMPLOYEE_ID
  FROM EMPLOYEES
 WHERE SALARY < ANY ( SELECT SALARY
                        FROM EMPLOYEES
                       WHERE JOB_ID = 'ABC'
                    )
   AND JOB_ID <> 'ABC';

3. 다중 컬럼 서브쿼리(Multi Column subquery)

: 서브쿼리 실행 결과로 여러 컬럼을 반환하고 이를 메인쿼리의 조건절에 여러 컬럼과 동시에 비교한다.
서브쿼리와 메인쿼리에서 비교하고자 하는 컬럼 개수와 위치가 동일해야한다.

MSSQL 지원 안함, Oracle SQL 지원

SELECT C1
       ,C2
       ,C3
  FROM T1
 WHERE (C1, C2) IN ( SELECT C1
                            ,C2
                       FROM T2
                      WHERE C2 = 'ABC'
                   );


위치에 따른 서브쿼리

1. SELECT절의 서브쿼리(스칼라 서브쿼리)

한 행의 한 컬럼만 반환한다.

SELECT NAME
       ,(SELECT AVG(AGE)
          FROM T2
       )
  FROM T1;

2. FROM절의 서브쿼리(인라인 뷰)

간단한 View의 개념

: 뷰는 SELECT구문을 데이터베이스에 저장한 것이다. 하지만 테이블과 달리 데이터를 보유하지 않는다.
-> 테이블의 모습을 한 SELECT구문

인라인 뷰

: FROM구에 직접 SELECT구문을 지정해 인라인 뷰로 사용한다. 이런 인라인 뷰는 SQL문이 실행될 때만 생성되는 동적인 뷰이다. (동적으로 조인 방식을 사용하는 것과 같다)

  • 프로그래머스 '입양 시각 구하기(1)' 문제를 통한 인라인 뷰 예제
  SELECT T.HOUR
         ,COUNT(T.HOUR) AS COUNT
    FROM (SELECT TO_CHAR(DATETIME, 'HH24') AS HOUR
            FROM ANIMAL_OUTS
         )T
   WHERE T.HOUR BETWEEN 9 AND 19
GROUP BY T.HOUR
ORDER BY T.HOUR;
  • 간단한 인라인 뷰 예제
SELECT T1.C1
       ,T2.C1
       ,T2.C2
  FROM T1 T1
       ,(SELECT C1
               ,C2
           FROM T2
       )T2
WHERE T1.C1 = T2.C1;

3. HAVING절의 서브쿼리

: HAVING절의 그룹핑된 결과에 대해 부가적인 조건을 줄 때 사용한다.

  SELECT T1.C1
         ,T2.C1
         ,AVG(T2.C2)
    FROM T1 T1
         ,T2 T2
   WHERE T1.C1 = T2.C1
GROUP BY T1.C1
         ,T2.C1
  HAVING AVG(T1.C2) < (SELECT AVG(C2)
                       FROM T2
                      WHERE T1 = 'ABC'
                    );

4. UPDATE문의 SET절 서브쿼리

UPDATE T1 T1
   SET T1.C1 = (SELECT C1
                  FROM T2
                 WHERE T1.C1 = T2.C1
               );

5. INSERT문의 VALUES절 서브쿼리

INSERT INTO T1 (
            C1
            ,C2
            ,C3
            )
     VALUES (
            (SELECT C1
               FROM T2
            )
            ,(SELECT C2
                FROM T2
            )
            ,(SELECT C3
                FROM T2
            )
            );
     
profile
안녕하세요😀😀

0개의 댓글