안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
상호연관 서브쿼리
- 상관 서브쿼리
- 메인쿼리의 값을 전달 받아 서브쿼리를 수행 후 결과 값을 메인쿼리에 반환하는 쿼리
- 일반 서브쿼리는 블럭 잡아서 단독으로 실행 가능한 반면, 상관 서브쿼리는 그렇지 않음
- 메인 쿼리의 매 행마다 다른 값을 서브쿼리에 전달
직급별 평균급여보다 많은 급여를 받는 사원 조회
[조인 버전]
select
e.emp_name, e.job_code, e.salary, s.avg_sal
from
employee e left join (
select
job_code,
trunc(avg(salary)) avg_sal
from
employee
group by
job_code
) s
on e.job_code = s.job_code
where
e.salary > s.avg_sal;
[상관서브쿼리 버전]
select
emp_name, job_code, salary
from
employee e
where
salary > (
select
trunc(avg(salary))
from
employee
where
job_code = e.job_code
);
선동일과 송종기의 정보로 예를 들어 설명해보자면, 메인 쿼리는 매 행마다 실행된다고 하였습니다.
따라서 처음 '선동일'의 행이 실행이 되었을 것이고, where절에 가니 salary > (서브쿼리~)를 만나게 됩니다.
서브쿼리를 실행하려고 보니 메인 쿼리의 e.job_code를 요구했죠.
그렇다면 현재 실행 중인 '선동일'의 job_code인 'J1'이 e.job_code에 넘어오게 됩니다.
그렇다면 서브쿼리의 where절에서 job_code = 'J1', 즉 job_code가 'J1'인 사원들을 추려내고 그에 대한 급여 평균을 구하고 다시 메인 쿼리에 해당 값을 넘겨주어 메인 쿼리의 where절을 실행 → true면 결과 집합 포함 / false면 미포함 하게 됩니다.'선동일'의 직급인 'J1'은 평균 급여가 800만원이므로 false! 결과 집합에 미포함 되었습니다.
그 후 다음 행으로 넘어가 '송종기' 행을 실행하게 되는데 위와 동일한 과정을 거친 후 '송종기'의 직급인 'J2'는 평균 급여가 472만원 대이므로, true! 결과집합에 포함 되었습니다.
이러한 과정을 거쳐 총 9명의 정보가 출력되었습니다.
부서코드별 평균 급여보다 많은 급여를 받는 사원 조회 (인턴사원 제외)
select
emp_name, dept_code, salary
from
employee e
where
salary > (
select
avg(salary)
from
employee
where
dept_code = e.dept_code
);
☞ exists 연산자
exists(서브쿼리)
- 서브쿼리의 결과 집합이 1행 이상인 경우에 true를 반환, 0행이면 false처리
부서 테이블에서 실제 부서원이 존재하는 부서인 지 조회
select
*
from
department d
where
exists(
select
1
from
employee
where
dept_code = d.dept_id
);
exists()는 서브쿼리의 결과 집합이 1행 이상이라면 true, 0행이라면 false를 리턴한다고 하였습니다.
마찬가지로 각 행마다 실행이 되는데 'D2', 'D3'의 부서코드를 예를 들어보겠습니다.
만일 현재 메인 쿼리에서 'D2'의 부서코드를 가진 행을 실행하였다고 했을 때 where절에서 exists(서브쿼리)를 만나 실행하게 될 것입니다.
여기서 메인쿼리에서 실행 중인 'D2'가 d.dept_id에 넘어오게 됩니다.
employee 테이블의 dept_code = 'D2'인 행을 추리게 되고 employee 테이블에서 dept_code가 'D2'인 행이 있기 때문에 true를 리턴하게 되어 결과집합에 포함시킵니다.
그 후 다음 행으로 넘어가 'D3'행을 실행하게 되고 위와 동일한 과정을 거치게 됩니다.하지만 employee 테이블에서 dept_code가 'D3'인 행이 없기 때문에 false를 리턴하게 되어 결과집합에 미포함시키게 되는 것입니다.
이러한 과정을 통해 위와 같은 결과가 출력되었습니다.
관리하는 사원이 있는 관리자 사원 조회
select
emp_name
from
employee e
where
exists(
select
1
from
employee
where
manager_id = e.emp_id
);
☞ not exists
- 서브쿼리가 행이 존재하면 false, 존재하지 않으면 true
select
emp_name
from
employee e
where
not exists(
select
1
from
employee
where
salary > e.salary -- 최대
-- salary < e.salary -- 최소
);
'DataBase > Oracle' 카테고리의 다른 글
고급쿼리) TOP-N 분석 (rownum) (0) | 2022.04.22 |
---|---|
SUB-QUERY) 스칼라 서브쿼리, inline-view (0) | 2022.04.22 |
SUB-QUERY) 단일/다중행 다중컬럼 서브쿼리 (0) | 2022.04.21 |
SUB-QUERY) 다중행 단일컬럼 서브쿼리 (any/some, all) (0) | 2022.04.21 |
SUB-QUERY) 단일행 단일컬럼 서브쿼리 (0) | 2022.04.21 |