본문 바로가기

[DB]DataBase/[SQL]

[SQLD] 서브 쿼리

728x90
반응형

서브쿼리

  • 하나의 SQL 문 안에 포함되어 있는 또 다른 SQL 문을 의미
  • 반드시 괄호로 묶어야 함
  • 예) SELECT 문 안에 SELECT 문

메인쿼리와 서브쿼리

서브쿼리 사용 가능한 곳

  1. SELECT 절
  2. FROM 절
  3. WHERE 절
  4. HAVING 절
  5. ORDER BY 절
  6. 기타 DML(INSERT, DELETE, UPDATE) 절

* GROUP BY 절은 사용 불가

 

서브쿼리 종류

1. 동작하는 방식에 따라

  • 비연관 (UN-CORRELATED) 서브쿼리
    • 서브쿼리가 메인쿼리 컬럼을 가지고 있지 않은 형태
    • 메인 쿼리에 서브 쿼리가 실행된 결과값을 제공하기 위한 목적으로 사용
  • 연관 (CORRELATED) 서브쿼리
    • 서브쿼리가 메인쿼리 컬럼을 가지고 있는 형태
    • 일반적으로 메인쿼리가 먼저 수행된 후에 서브쿼리에서 조건이 맞는지 확인하는 목적으로 사용

동작하는 방식에 따른 서브쿼리 분류

2. 위치에 따라

1) 스칼라 서브쿼리

  • SELECT에 사용하는 서브쿼리로, 마치 하나의 컬럼처럼 표현하기 위해 사용
  • 주로 서브쿼리 결과를 하나의 컬럼처럼 사용
  • 각 행마다 스칼라 서브쿼리 결과가 하나여야 함 (단일행 서브쿼리 형태)
  • 조인의 대체 연산

스칼라 서브쿼리 문장

2) 인라인뷰(Inline View)

  • FROM 절에 사용하는 서브쿼리
  • 서브쿼리의 결과가 마치 실행 시에 동적으로 생성된 테이블인 것처럼 사용
    • 주로 서브쿼리 결과를 테이블처럼 사용
    • 쿼리 안의 뷰 형태로 테이블처럼 조회할 데이터를 정의하기 위해 사용
    • 인라인 뷰는 SQL문이 실행될 때만 임시적으로 생성되는 동적인 뷰이기 때문에 데이터베이스에 해당 정보가 저장되지 않음
  • 테이블명이 존재하지 않기 때문에 다른 테이블과 조인시 반드시 테이블 별칭 명시 (단독으로 사용하는 경우는 불필요)
  • WHERE절 서브쿼리와 다르게 서브쿼리 결과를 메인 쿼리의 어느 절에서도 사용할 수 있음
  • 인라인뷰의 결과와 메인쿼리 테이블과 조인할 목적으로 주로 사용
  • 모든 연산자 사용 가능

인라인뷰 문장
뷰 사용의 장점

3) WHERE절 서브쿼리

  • 가장 일반적인 서브쿼리
  • 주로 비교 상수 자리에 값을 전달하기 위한 목적으로 사용 (상수항 대체)
  • 리턴 데이터의 형태에 따라 단일행 서브쿼리, 다중행 서브쿼리, 다중컬럼 서브쿼리, 상호연관 서브쿼리로 구분

WHERE절  서브쿼리 문장

  1. 단일행(Singel Row) 서브쿼리
    1. 서브쿼리 결과 1개의 행이 리턴되는 형태
    2. 단일행 서브쿼리 연산자 종류
    3. SELECT EMPNO, ENAME
      FROM EMP
      WHERE SAL > (SELECT AVG(SAL)
      			 FROM EMP)
      ;
  2. 다중행(Multi Row) 서브쿼리
    1. 서브쿼리 결과 여러 행이 리턴되는 형태
    2. 비교 연산자(여러 값이랑 비교할 수 없는 연산자) 사용 불가
    3. 다중행 서브쿼리 연산자
    4. 다중 행 비교 연산자
    5. > ALL(2000, 3000) : 최대값(3000)보다 큰 행들 반환 
      < ALL(2000, 3000) : 최소값(2000)보다 작은 행들 반환 
      > ANY(2000, 3000) : 최소값(2000)보다 큰 행들 반환 
      < ANY(2000, 3000) : 최대값(3000)보다 작은 행들 반환 
    6. SELECT EMPNO, ENAME
      FROM EMP
      WHERE SAL > ANY(SELECT SAL
      			 FROM EMP
                   WHERE DEPTNO = 10)
      ;
  3. 다중컬럼(Multi Column) 서브쿼리
    1. 서브쿼리 결과 여러 컬럼이 리턴되는 형태
    2. 메인쿼리와 비교컬럼이 2개 이상
    3. 대소 비교 전달 불가
    4. SELECT EMPNO, ENAME, SAL, DEPTNO
      FROM EMP
      WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL)
      			 FROM EMP
                   GROUP BY DEPTNO)
      ;
    5. 부서별 최대 급여가 여러 값이므로 비교할 경우 다중행 연산자인 IN을 사용함
  4. 상호연관 서브쿼리
    1.  메인쿼리와 서브쿼리의 비교를 수행
    2. 비교할 집단이나 조건은 서브쿼리에 명시
      1. 메인쿼리에는 서브쿼리 컬럼이 정의되지 않았기 때문에 에러 발생
    3. SELECT EMPNO, ENAME, SAL, DEPTNO
      FROM EMP E1
      WHERE SAL > (SELECT AVG(SAL)
      			 FROM EMP E2
                   WHERE E1.DEPTNO = E2.DEPTNO
                   GROUP BY DEPTNO)
      ;
    4. 상호연관 서브쿼리 연산순서
      1. 1) 메인쿼리 테이블 READ 
        2) 메인쿼리 WHERE 절 확인(SAL 확인) 
        3) 서브쿼리 테이블 READ 
        4) 서브쿼리 WHERE 절 확인(다시 E1.DEPTNO 요구) 
        5) E1.DEPTNO 값을 서브쿼리의 DEPTNO 컬럼과 비교하여 조건절 완성 
        6) 위 조건에 성립하는 행의 그룹연산 결과 확인(AVG(SAL) 
        7) 위 결과를 메인쿼리에 전달하여 해당 조건을 만족하는 행만 추출 
      2. 상호연관 서브쿼리 사용 시 GROUP BY 생략 가능

반환되는 데이터의 형태에 따른 서브쿼리 분류

서브쿼리 주의사항

  • 서브쿼리를 괄호로 감싸서 사용해야 함
  • 서브쿼리는 단일 행(Single Row) 또는 복수 행(Multiple Row) 비교 연산자와 함께 사용 가능
    • 단일 행 비교 연산자는 서브쿼리의 결과가 반드시 1건 이하여야 하고, 복수 행 비교 연산자는 서브쿼리의 결과 건수와 상관 없다.
  • 특별한 경우(TOP-N 분석 등)을 제외하고 서브 쿼리절에 ORDER BY절 사용 불가
    • ORDER BY 절은 SELECT절에서 오직 한 개만 올 수 있기 때문에 ORDER BY절은 메인 쿼리의 마지막 문장에 위치해야 한다.
  • 단일행 서브쿼리와 다중행 서브쿼리에 따라 연산자 선택이 중요

 

반응형

'[DB]DataBase > [SQL]' 카테고리의 다른 글

[SQLD] 그룹 함수  (0) 2024.05.09
[SQLD] 집합 연산자  (0) 2024.05.06
[SQLD] 표준 조인  (0) 2024.05.05
[SQLD] 순수 관계 연산자  (0) 2024.05.03
[SQLD] JOIN 조인  (0) 2024.05.02