Post

[DBP] CH1-2. Sub Query

[DBP] CH1-2. Sub Query

Sub Query (서브 질의)

  • 하나의 SQL문에 중첩된 SELECT문
  • 서브 질의는 주 질의 이전에 한 번 실행됨
  • 서브 질의의 결과는 주 질의에 의해 사용됨


  • 유형 : return 값이 어떤 유형인지
    • 단일 행(Single Row)
    • 다중 행(Multiple Rows)
    • 다중 열(Multiple Columns)


단일 행 서브 질의

  • 하나의 행 반환
  • 단일 행 연산자 =, >, >=, <, <=, <>, !=만 사용 가능
  • 비용이 적게 들어 효율적


  • ex) ‘SMITH’와 같은 job을 갖는 사원 이름, 사원 번호, 업무 출력
    1
    2
    3
    4
    5
    
      SELECT ename, empno, job
      FROM emp
      WHERE job = (SELECT job
                   FROM emp
                   WHERE ename = 'SMITH');
    
    • 서브 질의 -> ‘SMITH’의 job 반환
    • 서브 질의 결과 SMITH의 job사원들의 job 비교
      IMG_D68E7AB5E202-1


  • cf) Self Join은 비용이 큼 (메모리 많이 사용)
    1
    2
    3
    4
    
      SELECT e2.ename, e2.job
      FROM emp e1, emp e2
      WHERE e1.ename = 'SMITH'
      and e1.job = e2.job;
    


다중 행 서브 질의

  • 하나 이상의 행을 반환하는 서브 질의
  • 복수 행 연산자 IN, NOT IN, ANY, ALL, EXISTS 사용 가능


  • ex1) 부서별로 가장 급여를 많이 받는 사원 정보
    1
    2
    3
    4
    5
    6
    
      SELECT empno, ename, sal, deptno
      FROM emp
      WHERE (deptno, sal)
          IN (SELECT deptno, MAX(sql)
              FROM emp
              GROUP BY deptno);
    
    EMPNOENAMESALDEPTNO
    7698BLAKE285030
    7788SCOTT300020
    7902FORD300020
    7839KING500010
    • 다중열 - 다중행
    • 👀 (deptno, sal) : emp의 (deptno, sal) 중 서브 질의 결과와 일치하는 것!
    • 서브 질의 결과: 부서별 MAX(sal)의 empno, sal 반환
    DEPTNOMAX(SAL)
    302850
    203000
    105000


  • ex2) 30번 부서의 최소 급여를 받는 사원보다 많은 급여를 받는 사원의 사원 번호, 사원 이름, 급여, 업무 출력 (30번 부서 제외)
    1
    2
    3
    4
    5
    6
    7
    
      SELECT empno, ename, sal, job
      FROM emp
      WHERE deptno != 30
      and sal > ANY (SELECT sal
                     FROM emp
                     WHERE deptno = 30);
      -- MIN(sal)로 단일행 비교도 가능
    
    EMPNOENAMESALJOB
    7566JONES2975MANAGER
    7782CLARK2450MANAGER
    7788SCOTT3000ANALYST
    7839KING5000PRESIDENT
    7876ADAMS1100CLERK
    7902FORD3000ANALYST
    7934MILLER1300CLERK
    • 👀 ANY : 서브 질의 결과 중 어느 하나라도 -> 최소 급여와 비교하게 됨
    • 👀 ALL 로 바꾼다면 -> 30번 부서의 최고 급여를 받는 사원보다 많은 급여를 받는 사원 출력!
    • 서브 질의 결과 : 30번 부서의 급여들 모두 출력


다중 열 서브 질의

  • 서브 질의 결과값이 두 개 이상의 컬럼을 반환


  • ex1) 급여와 보너스가 부서 30에 있는 어떤 사원의 보너스와 급여에 일치하는 사원의 사원 번호, 사원 이름, 급여, 보너스 출력
    1
    2
    3
    4
    5
    6
    
      SELECT empno, ename, sal, comm
      FROM emp
      WHERE (sal, NVL(comm, -1))
          IN (SELECT sal, NVL(comm, -1)
              FROM emp
              WHERE deptno = 30);
    
    EMPNOENAMESALCOMM
    7499ALLEN1600300
    7521WARD1250500
    7654MARTIN12501400
    7698BLAKE2850 
    7844TURNER15000
    7900JAMES950 
    • 다중행 & 다중열 서브 질의
    • 👀 NVL : comm 값이 NULL이면 -1로 대치

      • NULL값도 연산이 가능하게끔!
      • NULL값을 그냥 두면 연산 안하고 건너뜀
        -> NULL이 있는 행은 출력되지 않음
    • 👀 IN : ‘어떤’ -> 서브 질의 결과들 중 일치하는 행이 있다면 출력


  • ex2) 업무별로 최소 급여를 받는 사원의 사원 번호, 이름, 업무, 부서 번호 출력
    1
    2
    3
    4
    5
    6
    
      SELECT empno, ename, job, deptno
      FROM emp
      WHERE (job, sal)
          IN (SELECT job, MIN(sal)
              FROM emp
              GROUP BY job);
    
    EMPNOENAMESALDEPTNO
    7788SCOTT300020
    7902FORD300020
    7369SMITH80020
    7782CLARK245010
    7839KING500010
    7521WARD125030
    7654MARTIN125030
This post is licensed under CC BY 4.0 by the author.