쿼리 안에 쿼리가 들어가 있는 형태를 서브 쿼리라 한다.

지금 까지 배운 쿼리로는 해결할 수 없기 때문에 복합적인 쿼리형태를 사용한다.(메인쿼리+서브쿼리)

서브쿼리는 괄호를 사용한다.

단일행 서브 쿼리

다중행 서브 쿼리

서브 쿼리로 부터 얻은 결괏값이 여러개 일때 사용한다.

IN

리스트 값과 동일하다는 의미 이다.

다중행 서브 쿼리

SELECT ename, sal
  FROM emp
  WHERE sal in (SELECT sal
                       FROM emp
                       WHERE job='SALESMAN');

다중열 서브 쿼리


SELECT *
FROM employees A 
 WHERE  (A.job_id ,A.salary )IN (SELECT job_id, MIN(salary) 최저급여
                     FROM employees
                     GROUP BY job_id
                     )
 order by A.salary DESC;     

NOT IN

리스트 값과 동일 하지 않다는 의미이다.

--NOT IN
  SELECT ename, sal, job,mgr
  FROM emp
  WHERE empno not in (SELECT mgr
                                  FROM emp
                                  WHERE mgr is not null);

  select * from emp;

EXISTS 와 NOT EXISTS

특정 테이블의 데이터가 다른 테이블에도 존재하는지 여부를 확인하는 방법이다

EXISTS

select * 
    from dept d
    where EXISTS (SELECT * 
                    FROM emp e
                    WHERE e.deptno=d.deptno);

NOT EXISTS

SELECT *
  FROM dept d
  WHERE NOT EXISTS (SELECT *
                      FROM emp e
                      WHERE e.deptno = d.deptno);

4)기타

>all: 리스트의 값보다 크다.
>any:리스트의 가장 작은 값보다 크다.
<all:리스트의 가장 작은 값보다 작다
<any: 리스트의 가장 큰 값보다 작다.

서브 쿼리 위치에 따른 서브쿼리 종류

사용 위치에 따라 서브 쿼리를 분류한다.

KakaoTalk_20220519_101756909_01.jpg

1)select 절에 있는 서브쿼리 - 스칼라 서브쿼리

2)from 절에 있는 서브쿼리 - 인라인뷰

3)where 절에 있는 서브쿼리 - 서브쿼리

4)Where절의 결과값에 따른 분류

from 절에 있는 서브쿼리 - 인라인뷰

--이름과 월급을 출력하는데 순위가 1위 인 사람만 출력하시오.
 SELECT v.ename, v.sal, v.순위
 FROM ( SELECT ename, sal, rank() over (order by sal desc) 순위
               FROM emp) v
  WHERE v.순위 =1;
#HR
select * 
        from employees A,
        --     ( 서브 쿼리:인라인 뷰)B
        (select department_id
          from departments
          where department_name ='IT') B
  WHERE A.department_id = B.department_id ;

HAVING절의 서브 쿼리

그룹 함수는 안된다.

--직업과 직업별 토탈 월급을 출력하는데 , 직업이 SALESMAN인 사람들의 토탈 월급보다 
   --더 큰 값들만 출력하시오.
   
   select job,sum(sal)
        from emp
        where sum(sal) > (select sum(sal) from emp 
                           where job ='SALSMAN') --직업이 SALESMAN인 사람들  더 큰 값
        group by job;  --ORA-00934: group function is not allowed here

ORA-00934: group function is not allowed here

SELECT job, sum(sal)
  FROM emp
  GROUP BY job
  HAVING sum(sal) > (SELECT sum(sal)
                       FROM emp
                       WHERE job='SALESMAN');

8.select 절에 있는 서브쿼리 - 스칼라 서브쿼리

서브 쿼리 캐싱을 이용하여 수행된다.

--select 절에 있는 서브쿼리 - 스칼라 서브쿼리
 --직업이 SALESMAN인 사원들의 이름과 월급을 출력하는데,SALESMAN인 사원들의 
 --최대 월급과 최소 월급도 같이 출력하시오.

select  ename,sal,max(sal) 최대월급,
                  min(sal) 최소월급
 from emp
 where job='SALESMAN';
 --ORA-00937: not a single-group group function

 select  ename,sal,(select  max(sal) from emp where job='SALESMAN') 최대월급,
                   (select  min(sal) from emp where job='SALESMAN') 최소월급
 from emp
 where job='SALESMAN';

select max(sal) from emp where job='SALESMAN' 절을 레코드 마다 계산 하면 데이터베이스 효율이 떨어진다. 첫번째 행은 계산하지만 두번째 행부터는 계산 하지 않고 캐싱을 한다.(서브쿼리 캐싱)