서브쿼리
Main query와 Subquery
- Subquery 는 SELECT 문 내에 다시 SELECT 문을 사용하는 SQL 문이다.
- Subquery 의 형태는 FROM 구에 SELECT 문을 사용하는 인라인 뷰(Inline View)와 SELECT 문에 Subquery 를 사용하는 스칼라 서브쿼리(Scala Subquery) 등이 있다.
- WHERE 구에 SELECT 문을 사용하면 서브쿼리(Subquery) 라고 한다.
Main Query 와 Subquery
SELECT *
FROM EMP
WHERE
DEPTNO =
(SELECT DEPTNO
FROM DEPT
WHERE
DEPTNO = 10
);
- 위의 예시에 WHERE 구에 있는 SELECT 문은 서브쿼리(Subquery)이고 괄호 내에 SELECT 문을 사용한다.
- 서브쿼리 밖에 있는 SELECT 문은 메인 쿼리(Main Query) 이다.
인라인 뷰(Inline View)
SELECT *
FROM (
SELECT ROWNUM NUM, ENAME
FROM EMP) a
WHERE
NUM < 5;
- FROM 구에 SELECT 문을 사용하여 가상의 테이블을 만드는 효과를 얻을 수 있다.
- 이렇게 FROM 구에 SELECT 문을 사용한 것이 인라인 뷰(Inline View)이다.
단일 행 서브쿼리와 다중 행 서브쿼리
- 서브쿼리(Subquery)는 반환하는 행 수가 한 개인 것과 여러 개인 것에 따라서 단일 행 서브쿼리와 멀티 행 서브쿼리로 분류된다.
- 단일 행 서브쿼리는 단 하나의 행만 반환하는 서브쿼리로 비교 연산자(=, <, <=, >=, <>)를 사용한다.
- 다중 행 서브쿼리는 여러 개의 행을 반환하는 것으로 IN, ANY, ALL, EXISTS 를 사용해야 한다.
서브쿼리 종류(반환 행)
서브쿼리 종류 | 설명 |
---|
단일 행 서브쿼리(Single Row Subquery) | - 서브쿼리를 실행하면 그 결과는 반드시 한 행만 조회된다. |
| - 비교 연산자인 =, <, <=, >, >=, <> 를 사용한다. |
다중 행 서브쿼리(Multi Row Subquery) | - 서브쿼리를 실행하면 그 결과는 여러 개의 행이 조회된다. |
| - 다중 행 비교 연산자인 IN, ANY, ALL, EXISTS를 사용한다. |
다중 행(Multi Row) 서브쿼리
- 다중 행 서브쿼리는 서브쿼리 결과가 여러 개의 행을 반환하는 것으로 다중 행 연산자를 사용해야 한다.
가중 행 비교 연산자
다중 행 연산 | 설명 |
---|
IN (Subquery) | Main Query 의 비교조건이 Subquery 의 결과 중 하나만 동일하면 참이 된다.(OR 조건) |
ALL (Subquery) | - Main query 와 Subquery 의 결과가 모두 동일하면 참이 된다. |
| - < ALL : 최솟값을 반환한다. |
| - > ALL : 최댓값을 반환한다. |
ANY(Subquery) | - Main query의 비교조건이 Subquery 의 결과 중 하나 이상 동일하면 참이 된다. |
| - < ANY : 하나라도 크게 되면 참이 된다. |
| - > ANY : 하나라도 작게 되면 참이 된다. |
EXISTS(Subquery) | Main query 와 Subquery 의 결과가 하나라도 존재하면 참이 된다. |
IN
- IN 은 반환되는 여러 개의 행 중에서 하나만 참이 되어도 참이 되는 연산이다.
SELECT
ENAME, DNAME, SAL
FROM EMP, DEPT
WHERE
EMP.DEPTNO = DEPT.DEPTNO
AND EMP.EMPNO
IN (
SELCT EMPNO
FROM EMP
WHERE SAL > 2000
);
ALL
- 메인쿼리와 서브쿼리의 결과가 모두 동일하면 참이 된다.
SELECT *
FROM EMP
WHERE
DEPTNO <= ALL (20, 30);
EXISTS
- EXISTS 는 Subquery 로 어떤 데이터 존재 여부를 확인하는 것이다.
- 즉, EXISTS 의 결과는 참과 거짓이 반환된다.
SELECT
ENAME, DNAME, SAL
FROM EMP, DEPT
WHERE
EMP.DEPTNO = DEPT.DEPTNO
AND EXSITS (
SELECT 1
FROM EMP
WHERE SAL > 2000
);
스칼라(Scala) 서브쿼리
- 스칼라 서브쿼리는 반드시 한 행과 한 칼럼만 반환하는 서브쿼리이다.
- 만약 여러 행이 반환되면 오류가 발생한다.
SELECT
ENAME AS "이름",
SAL AS "급여",
(SELECT AVG(SAL FROM EMP) AS "평균급여"
FROM EMP
WHERE
EMPNO = 1000;
- 앞의 예시처럼 직원 급여를 조회할 때 평균 급여를 같이 계산하여 조회한다.
- 스칼라 서브쿼리를 사용해서 직원의 평균 급여를 계산한 것이다.
- 연관 서브쿼리는 서브쿼리 내에서 Main Query 내의 컬럼을 사용하는 것을 의미한다.
FROM EMP a
WHERE
a.DEPTNO = ( SELECT DEPTNO FROM DEPT b WHERE B.DEPTNO = a.DEPTNO);
- a 와 a.DEPTNO 는 연관 서브쿼리이다.
- Main Query 에서 데이터를 받아 Subquery를 실행한다.