DBMS - Oracle Database
VERSION - Oracle Database 11g Release 2
IDE - SQL Developer
실습용 데이터를 입력하지 않고, 오라클 데이터베이스를 설치하면 기본으로 제공되는 테이블과 계정들로 학습한 내용입니다.
※ 서브쿼리
1. 서브쿼리란?
서브쿼리(Subquery)는 SQL문을 실행하는 데 필요한 데이터를 추가로 조회하기 위해 SQL문 내부에서 사용하는 SELECT문을 의미한다.
SELECT * FROM EMP
WHERE SAL > (SELECT SAL
FROM EMP
WHERE ENAME = 'JONES');
결과 >>
# 서브쿼리의 특징
- 서브쿼리는 연산자와 같은 비교 또는 조회 대상의 오른쪽에 놓이며 괄호 ( )로 묶어서 사용한다.
- 특수한 몇몇 경우를 제외한 대부분의 서브쿼리에서는 ORDER BY절을 사용할 수 없다.
- 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 갯수로 지정해야 한다. 즉 메인쿼리의 비교 대상 데이터가 하나라면 서브쿼리의 SELECT절 역시 같은 자료형인 열을 하나 지정해야 한다.
- 서브쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류의 호환 가능해야 한다. 예를 들어 메인쿼리에 사용한 연산자가 단 하나의 데이터로만 연산이 가능한 연산자라면 서브쿼리의 결과 행 수는 반드시 하나여야 한다.
※ 실행 결과가 하나인 단일행 서브쿼리
: 실행 결과가 단 하나의 행으로 나오는 서브쿼리
단일행 연산자 | |||||||
> | >= | = | <= | < | <> | ^= | != |
초과 | 이상 | 같은 | 이하 | 미만 | 같지 않음 |
1. 단일행 서브쿼리와 날짜형 데이터
SELECT * FROM EMP
WHERE HIREDATE < (SELECT HIREDATE
FROM EMP
WHERE ENAME = 'JAMES');
결과 >>
2. 단일형 서브쿼리와 함수
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL,
D.DEPTNO, D.DNAME, D.LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO = 20
AND E.SAL > (SELECT AVG(SAL)
FROM EMP);
결과 >>
※ 실행 결과가 여러 개인 다중행 서브쿼리
: 실행 결과 행이 여러 개로 나오는 서브쿼리
다중행 연산자 | 설명 |
IN | 메인쿼리의 데이터가 서브쿼리의 결과 중 하나라도 일치한 데이터가 있다면 true |
ANY, SOME | 메인쿼리의 조건식을 만족하는 서브쿼리의 결과가 하나 이상이면 true |
ALL | 메인쿼리의 조건식을 서브쿼리의 결과 모두가 만족하면 true |
EXISTS | 서브쿼리의 결과가 존재하면(즉, 행이 1개 이상일 경우) true |
1. IN 연산자
SELECT * FROM EMP
WHERE SAL IN (SELECT MAX(SAL)
FROM EMP
GROUP BY DEPTNO);
2. ANY, SOME 연산자
: 서브쿼리가 반환한 여러 결과 값 중 메인쿼리와 조건식을 사용한 결과가 하나라도 true라면 메인쿼리 조건식을 true로 반환해 주는 연산자이다.
SELECT * FROM EMP
WHERE SAL < ANY (SELECT SAL
FROM EMP
WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;
결과 >>
3. ALL 연산자
: ANY, SOME과 달리 서브쿼리의 모든 결과가 조건식에 맞아떨어져야만 메인쿼리의 조건식이 true가 되는 연산자이다.
SELECT * FROM EMP
WHERE SAL < ALL (SELECT SAL
FROM EMP
WHERE DEPTNO = 30);
결과 >> ANY 연산자를 사용했을 때와는 다른 결과 출력
ALL 연산자가 의미하는 것과 같이 서브쿼리의 모든 결과 값(950, 1250, 1500, 1600, 2850)보다 작은 값을 가진 메인쿼리의 행만 true가 되어 출력된다.
4. EXISTS 연산자
: 서브쿼리에 결과 값이 하나 이상 존재하면 조건식이 모두 true, 존재하지 않으면 모두 false가 되는 연산자이다.
SELECT * FROM EMP
WHERE EXISTS (SELECT DNAME
FROM DEPT
WHERE DEPTNO = 10);
결과 >>
SELECT * FROM EMP
WHERE EXISTS (SELECT DNAME
FROM DEPT
WHERE DEPTNO = 50);
결과 >>
EXIST 연산자는 다른 다중행 연산자에 비해 그리 자주 사용하는 편은 아니지만, 특정 서브쿼리 결과 값의 존재 유무를 통해 메인쿼리의 데이터 노출 여부를 결정해야 할 때 간혹 사용한다.
※ 비교할 열이 여러 개인 다중열 서브쿼리
: 서브쿼리의 SELECT절에 비교할 데이터를 여러 개 지정하는 방식 (= 복수열 서브쿼리라고도 부른다.)
SELECT * FROM EMP
WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL)
FROM EMP
GROUP BY DEPTNO);
결과 >>
※ SELECT절에 사용하는 서브쿼리
: 흔히 스칼라 서브쿼리(scalar subquery)라고 부르는 이 서브쿼리는 SELECT절에 하나의 열 영역으로서 결과를 출력할 수 있다.
SELECT EMPNO, ENAME, JOB, SAL,
(SELECT GRADE FROM SALGRADE
WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE,
DEPTNO,
(SELECT DNAME FROM DEPT
WHERE E.DEPTNO = DEPT.DEPTNO) AS DNAME
FROM EMP E;
결과 >>
SELECT절에 명시하는 서브쿼리는 반드시 하나의 결과만 반환하도록 작성해 주어야 한다.
Reference
|
댓글