728x90
반응형
서브쿼리
- 하나의 SQL 문 안에 포함되어 있는 또 다른 SQL 문을 의미
- 반드시 괄호로 묶어야 함
- 예) SELECT 문 안에 SELECT 문
서브쿼리 사용 가능한 곳
- SELECT 절
- FROM 절
- WHERE 절
- HAVING 절
- ORDER BY 절
- 기타 DML(INSERT, DELETE, UPDATE) 절
* GROUP BY 절은 사용 불가
서브쿼리 종류
1. 동작하는 방식에 따라
- 비연관 (UN-CORRELATED) 서브쿼리
- 서브쿼리가 메인쿼리 컬럼을 가지고 있지 않은 형태
- 메인 쿼리에 서브 쿼리가 실행된 결과값을 제공하기 위한 목적으로 사용
- 연관 (CORRELATED) 서브쿼리
- 서브쿼리가 메인쿼리 컬럼을 가지고 있는 형태
- 일반적으로 메인쿼리가 먼저 수행된 후에 서브쿼리에서 조건이 맞는지 확인하는 목적으로 사용
2. 위치에 따라
1) 스칼라 서브쿼리
- SELECT에 사용하는 서브쿼리로, 마치 하나의 컬럼처럼 표현하기 위해 사용
- 주로 서브쿼리 결과를 하나의 컬럼처럼 사용
- 각 행마다 스칼라 서브쿼리 결과가 하나여야 함 (단일행 서브쿼리 형태)
- 조인의 대체 연산
2) 인라인뷰(Inline View)
- FROM 절에 사용하는 서브쿼리
- 서브쿼리의 결과가 마치 실행 시에 동적으로 생성된 테이블인 것처럼 사용
- 주로 서브쿼리 결과를 테이블처럼 사용
- 쿼리 안의 뷰 형태로 테이블처럼 조회할 데이터를 정의하기 위해 사용
- 인라인 뷰는 SQL문이 실행될 때만 임시적으로 생성되는 동적인 뷰이기 때문에 데이터베이스에 해당 정보가 저장되지 않음
- 테이블명이 존재하지 않기 때문에 다른 테이블과 조인시 반드시 테이블 별칭 명시 (단독으로 사용하는 경우는 불필요)
- WHERE절 서브쿼리와 다르게 서브쿼리 결과를 메인 쿼리의 어느 절에서도 사용할 수 있음
- 인라인뷰의 결과와 메인쿼리 테이블과 조인할 목적으로 주로 사용
- 모든 연산자 사용 가능
3) WHERE절 서브쿼리
- 가장 일반적인 서브쿼리
- 주로 비교 상수 자리에 값을 전달하기 위한 목적으로 사용 (상수항 대체)
- 리턴 데이터의 형태에 따라 단일행 서브쿼리, 다중행 서브쿼리, 다중컬럼 서브쿼리, 상호연관 서브쿼리로 구분
- 단일행(Singel Row) 서브쿼리
- 서브쿼리 결과 1개의 행이 리턴되는 형태
단일행 서브쿼리 연산자 종류 -
SELECT EMPNO, ENAME FROM EMP WHERE SAL > (SELECT AVG(SAL) FROM EMP) ;
- 다중행(Multi Row) 서브쿼리
- 서브쿼리 결과 여러 행이 리턴되는 형태
- 비교 연산자(여러 값이랑 비교할 수 없는 연산자) 사용 불가
다중행 서브쿼리 연산자 다중 행 비교 연산자 - > ALL(2000, 3000) : 최대값(3000)보다 큰 행들 반환
< ALL(2000, 3000) : 최소값(2000)보다 작은 행들 반환
> ANY(2000, 3000) : 최소값(2000)보다 큰 행들 반환
< ANY(2000, 3000) : 최대값(3000)보다 작은 행들 반환 -
SELECT EMPNO, ENAME FROM EMP WHERE SAL > ANY(SELECT SAL FROM EMP WHERE DEPTNO = 10) ;
- 다중컬럼(Multi Column) 서브쿼리
- 서브쿼리 결과 여러 컬럼이 리턴되는 형태
- 메인쿼리와 비교컬럼이 2개 이상
- 대소 비교 전달 불가
-
SELECT EMPNO, ENAME, SAL, DEPTNO FROM EMP WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL) FROM EMP GROUP BY DEPTNO) ;
- 부서별 최대 급여가 여러 값이므로 비교할 경우 다중행 연산자인 IN을 사용함
- 상호연관 서브쿼리
- 메인쿼리와 서브쿼리의 비교를 수행
- 비교할 집단이나 조건은 서브쿼리에 명시
- 메인쿼리에는 서브쿼리 컬럼이 정의되지 않았기 때문에 에러 발생
-
SELECT EMPNO, ENAME, SAL, DEPTNO FROM EMP E1 WHERE SAL > (SELECT AVG(SAL) FROM EMP E2 WHERE E1.DEPTNO = E2.DEPTNO GROUP BY DEPTNO) ;
- 상호연관 서브쿼리 연산순서
- 1) 메인쿼리 테이블 READ
2) 메인쿼리 WHERE 절 확인(SAL 확인)
3) 서브쿼리 테이블 READ
4) 서브쿼리 WHERE 절 확인(다시 E1.DEPTNO 요구)
5) E1.DEPTNO 값을 서브쿼리의 DEPTNO 컬럼과 비교하여 조건절 완성
6) 위 조건에 성립하는 행의 그룹연산 결과 확인(AVG(SAL)
7) 위 결과를 메인쿼리에 전달하여 해당 조건을 만족하는 행만 추출 - 상호연관 서브쿼리 사용 시 GROUP BY 생략 가능
- 1) 메인쿼리 테이블 READ
서브쿼리 주의사항
- 서브쿼리를 괄호로 감싸서 사용해야 함
- 서브쿼리는 단일 행(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 |