Sql
scalar subquery 두 개 이상의 값을 리턴하고 싶을 때
pakker
2021. 3. 31. 12:52
scalar subquery 쿼리 내장된 또다른 쿼리 블록을 서브쿼리라고 하는데, 그 중에서 함수처럼 한 레코드 당 정확히 하나의 값 만을 리턴하는 서브 쿼리를 'scalar subquery' 라고 한다. scalar subquery는 주로 select-list에서 사용되지만 몇가지 예외사항을 뺀다면 칼럼이 올 수 있는 대부분 위치에서 사용 가능하다.
아래 쿼리는 위치가 'CHICAGO' 인 부서만 대상으로 급여 수준을 집계
사원(emp) 테이블 전체를 다 읽어야 하는 비효율이 있다.
select d.deptno, d.dname, avg_sal, min_sal, max_sal
from dept d
right outer join (select deptno, avg(sal) avg_sal, min(sal) min_sal, max(sal) max_sal
from emp
group by deptno) e on e.deptno = d.deptno
where d.loc= 'CHICAGO'
아래와 같이 바꾸면 좋겠지만 스칼라 서브쿼리는 한 레코드당 하나의 값만 리턴한다는 특징이 있다.
select d.deptno, d.dname,
(select avg(sal), min(sal), max(sal) from emp where deptno=d.deptno)
where d.loc= 'CHICAGO'
그렇다고 하단같이 쿼리 작성하면 emp에서 같은 범위를 반복적으로 엑세스 하는 비효율이 생긴다.
select d.deptno, d.dname,
(select avg(sal) from emp where deptno=d.deptno),
(select min(sal) from emp where deptno=d.deptno),
(select max(sal) from emp where deptno=d.deptno)
from dept d
where d.loc= 'CHICAGO'
이럴 땐, 구하고자 하는 값들을 모두 결합 후 바깥쪽 액세스 쿼리에서 substr 함수로 분리한다.
실행 순서가 from 이 select보다 앞서므로 가능 하다...!!!!!
select deptno, dname,
to_number(substr(sal, 1,7)) avg_sal,
to_number(substr(sal, 8,7)) min_sal,
to_number(substr(sal,15)) max_sal
from (
select d.deptno, d.dname, (select lpad(avg(sal),7) || lpad(min(sal),7) || max(sal)
from emp where deptno = d.deptno) sal
from dept d
where d.loc='CHICAGO'
)