subquery란?
- select, insert, update, delete에 포함된 쿼리를 말합니다.
- subquery는 반드시 () 안에 기술됩니다.
outerquery란?
- subquery를 포함하는 query를 말합니다.
id가 14인 임직원보다 생일이 빠른 직원 출력
select id, name, birth_date
from employee
where birth_date < (
select birth_date
from employee
where id = 14
);
id가 1인 임직원과 같은 부서, 성별인 임직원들의 id, 이름, 직군을 출력
select id, name, position
from employee
where (dept_id, sex) = (
select dept_id, sex
from employee
where id = 1
);
- subquery의 결과가 하나 이상이고 하나 이상의 결과를 return하는 subquery를 비교할 때는 ()를 이용해서 비교할 attribute를 지정할 수 있습니다.
id가 5인 임직원이 참여한 프로젝트에 참여한 임직원 출력
select distinct empl_id
from works_on
where empl_id != 5 and proj_id in (
select proj_id
from works_on
where empl_id = 5
);
- works_on 테이블에서 해당 임직원이 참여한 프로젝트 id를 찾는 subquery를 통해서 proj_id를 찾아내고 이와 동일환 proj_id를 가진 임직원의 id를 출력하였습니다.
- in은 여러개의 조건들중 하나라도 같다면 true를 return 합니다. 반대로 not in은 모든 값과 값이 다르면 true를 return 합니다.
subquery를 통한 가상의 테이블
select id, name
from employee as a,
(
select distinct empl_id
from works_on
where empl_id != 5 and proj_id in (
select proj_id
from works_on
where empl_id = 5
)
) as b
where a.id = b.empl_id;
- from 절에 subquery를 이용해서 임시 테이블을 만들어서 query문에 사용할 수 있습니다. 즉, subquery는 where절이 아닌 부분에서 사용될 수 있습니다.
exists
select p.id, p.name
from project as p
where exists (
select *
from works_on as w
where w.proj_id = p.id and w.empl_id in (7, 12)
);
- id가 7 또는 12인 임직원이 참여한 프로젝트의 id와 name을 출력하는 쿼리입니다. 여기서 exists는 ()안에 subquery가 하나의 row라도 return한다면 true를 return 하는 조건절입니다. 그의 반대로는 not exists가 있습니다.
리더보다 높은 연봉을 받는 부서원을 가진 리더의 id, name, salary, 그리고 해당 부서의 가장 높은 연봉을 출력
select e.id, e.name, e.salary,
(
select max(salary)
from employee
where dept_id = e.dept_id
) as dept_max_salary
from department as d, employee as e
where d.leader_id = e.id and e.salary < any (
select salary
from employee
where id != d.leader_id and dept_id = e.dept_id
);
- any는 subquery가 반환한 결과들 중에 단 하나라도 v와의 비교 연산이 true라면 true를 반환합니다. ( some을 사용할 수도 있는데 some과 any는 같은 역할을 합니다. )
- attribute 절에 subquery를 사용할 수 있습니다.
id가 13인 임직원과 한 번도 같은 프로젝트에 참여하지 못한 임직원들의 id, name, dept_id를 출력
select distinct e.id, e.name, e.dept_id
from employee as e, works_on as w
where e.id = w.empl_id
and w.proj_id != all(
select proj_id
from works_on
where empl_id = 13
);
- all은 subquery가 반환환 결과들을 비교 연산하여 모두 true 라면 true를 반환합니다. ( all 대신 not in을 사용할 수도 있습니다. )