DQL> Select - 서브 쿼리
메인 쿼리 서브 쿼리를 포함하고 있는 문장.
서브 쿼리 Select 문장 안에 포함된 또 하나의 Select 문
1. 단일행 서브쿼리
- 메인 쿼리의 검색 결과가 1개만 반환된다.
- 메인 쿼리의 조건 절에서 비교 연산자만 사용 가능하다.
ex) >=, >, != ...
서브 쿼리를 사용하지 않고 SCOTT 사원이 소속된 부서명을 출력한다면?
다음과 같이 두 번에 걸쳐 각각의 결과를 출력하게 된다.
select deptno from emp where ename='SCOTT'; -- deptno : 20
select dname from dept where deptno=20; -- dname : RESEARCH
먼저 'SCOTT'의 부서 번호를 검색
해당 부서 번호의 부서명 검색
서브 쿼리를 사용한다면 'SCOTT'의 부서 번호를 찾아 그 부서명을 찾아주는 SQL문을
한 문장에 작성하고 한번에 결과를 출력할 수 있다.
이때 괄호 안쪽을 서브 쿼리,
괄호 바깥 쪽을 메인 쿼리라고 할 수 있다.
select dname 부서 from dept where deptno = (select deptno from emp where ename='SCOTT');
2. 다중행 서브쿼리
- 메인 쿼리의 검색 결과가 하나 이상의 행이다.
- 메인 쿼리의 조건 절에서 다중 행 연산자를 사용한다.
2-1. in 연산자
서브 쿼리의 결과 중 하나라도 일치하면 참
Q. 급여가 3000이상인 사원이 소속된 부서와 동일한 부서에서 근무하는 사원을 구하기
1) 급여가 3000 이상인 사원이 소속된 부서를 찾는 SQL문을 먼저 적어본다.
select distinct deptno from emp where sal >= 3000;
-- 20번 부서가 두 번 출력되어서 distinct를 넣었다.
2) 이 10번, 20번 부서에서 근무하는 사원들의 명단을 출력해본다.
select deptno, ename, sal from emp
where deptno in
(select deptno from emp where sal>=3000);
-- 1에서 적어본 SQL문이 서브 쿼리가 된다.
10번 부서 or 20번 부서에서 근무하며 급여가 3000이상인 사원들의 명단이다.
(or = in)
2-2. all 연산자
서브 쿼리의 모든 결과가 일치해야 참
최대값보다 더 크면 참이 된다.
Q. 영업사원보다 급여를 많이 받는 사원들의 이름과 급여와 직급을 출력하기 (영업사원은 제외하고 표시)
1) 영업사원들의 급여를 출력해본다.
select sal from emp where job='SALESMAN';
1250, 1500, 1600 이 모든 값보다 큰 값이 급여 컬럼에 입력된 사원만 추출해야 한다.
2) 1에서 구한 모든 값보다 큰 값을 출력하는 SQL문을 작성한다. (영업사원은 제외하고 출력해야 한다.)
select ename, sal, job from emp
where sal > all
(select sal from emp where job='SALESMAN')
and job!='SALESMAN';
2-3. any 연산자
서브 쿼리의 값 중 가장 작은, 최소값보다 크면 참이 된다.
Q. 부서번호가 30번인 사원들의 급여 중에서 가장 적게 받는 사원보다 많은 급여를 받는 사원의 이름, 급여, 부서번호를 출력
1) 30번 부서 소속 사원들의 급여를 출력.
select sal from emp where deptno=30;
2) 영업사원 중 가장 적은 급여는 950이다. 이 950보다 크기만 하면 된다.
영업사원은 출력하지 않는 조건을 추가해본다.
select ename, sal, deptno from emp
where sal > any
(select sal from emp where deptno=30)
and deptno!=30;