[SQL] SQL 서브 쿼리(Sub-Query)

JUNBEOM PARK·2022년 3월 10일

💡 SQL

목록 보기
7/7
post-thumbnail

🤔 서브쿼리(Sub-Query) ?

하나의 쿼리 문장 내에 포함된 또 하나의 쿼리문장.
반드시 괄호 안에 넣어야 한다.
메인 쿼리가 실행되기 이전에 한 번만 실행된다.

서브쿼리를 각각의 어느 위치에서 사용하느냐에 따라 나누어 진다.



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

스칼라 서브쿼리(Scalar Subqueries)라고 불리며 SELECT절 안에 서브쿼리가 있다.

이 때, 서브쿼리의 결과는 반드시 단일 행이나 SUM, COUNT등의 집계 함수를 거친 단일 값으로 리턴 되어야 한다.

이유는 서브쿼리를 끝마친 값하나를 메인쿼리에서 SELECT 하기 때문이다.


구문

SELECT 학생이름,
       (  SELECT 학과.학과이름
            FROM 학과
           WHERE 학과.학과ID = 학생.학생ID ) AS 학과이름
  FROM 학생
 WHERE 학생이름 = '홍길동' ;




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

인라인뷰(Inline Views)라고 불리며 FROM절 안에 서브쿼리가 있다.

이 때, 서브쿼리의 결과는 반드시 하나의 테이블로 리턴되어야 한다.

이유는 서브쿼리를 끝마친 테이블 하나를 메인쿼리의 FROM에서 테이블로 잡기 때문이다.


구문

SELECT 학생이름, 수학점수
  FROM ( SELECT 학생.학생이름 AS 학생이름,
                과목.과목점수 AS 수학점수
           FROM 학생, 과목
          WHERE 학생.학생이름 = 과목.학생이름
            AND  과목.과목이름 = '수학' ) ;




3. WHERE절 서브쿼리(중첩 서브쿼리)

중첩 서브쿼리(Nested Subqueries)라고 불리며 WHERE절 안에 서브쿼리가 있다.

가장 자주 쓰이는 대중적인 서브쿼리이며 단일행과 다중행 둘 다 리턴이 가능하다.


SELECT *
  FROM 학생
 WHERE 학생.학생이름 IN ( SELECT 과목.학생이름 FROM 과목 WHERE 과목.과목이름 = '수학' ) ;


3-1 단일행 서브쿼리

  • 서브쿼리의 수행결과가 오직 하나의 ROW(행)만을 반환한다.
  • 이 하나의 결과를 가지고 메인쿼리는 비교연산자를 통해 쿼리를 수행한다.
  • 비교연산자는 단일행 비교연산자를 사용한다. (>,>=,<,<=,=,...)

// ex ) 사원들의 평균 급여보다 더 많은 급여를 받는 사원을 검색
SELECT  ENAME, SAL
  FROM  EMP
 WHERE  SAL > ( SELECT  AVG(SAL)
                  FROM  EMP);

3-2 다중행 서브쿼리

  • 서브쿼리의 수행결과가 두 개 이상의 ROW(행)을 반환한다.
  • 비교연산자는 다중행 비교연산자를 사용한다. (IN, ANY, ALL, EXISTS, ....)

IN
메인쿼리의 비교조건이 서브쿼리의 결과중에서 하나라도 일치하면 참.

ALL
메인쿼리의 비교조건이 서브쿼리의 검색결과와 모든 값이 일치하면 참

  • 메인쿼리 < ALL(서브쿼리) : 서브쿼리의 결과와 비교하여 최소값 반환
  • 메인쿼리 > ALL(서브쿼리) : 서브쿼리의 결과와 비교하여 최대값 반환

// ex ) 30번 소속 사원들 중 급여를 가장 많이 받는 사원보다 더 많은 급여를 받는 사람의 이름과 급여를 출력
SELECT  ENAME, SAL
  FROM  EMP
 WHERE  SAL > ALL ( SELECT  SAL
                      FROM  EMP
                     WHERE  DEPTNO = 30 );

ANY
메인쿼리의 비교조건이 서브쿼리의 검색결과와 하나 이상이 일치하면 참.

  • 메인쿼리 < ANY(서브쿼리) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 작다면 최소값 반환
  • 메인쿼리 > ANY(서브쿼리) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 크다면 최대값 반환.

EXISTS

  • 메인쿼리의 비교조건이 서브쿼리의 검색결과중에 하나라도 만족하는 값이 존재하면 참
  • EXISTS는 해당 로우가 존재하는지의 여부만 확인
  • IN은 실제 존재하는 데이터들의 모든 값까지 확인
  • NOT EXISTS는 메인쿼리의 컬럼명과 서브쿼리의 컬럼명을 비교하여 일치하지 않으면 메인쿼리 테이블의 모든 ROW(행)을 반환
profile
DB 엔지니어👍

0개의 댓글