나만 알 수 없어서 만든 블로그

1.5 DATABASE 서브쿼리 VS 스칼라쿼리 (각각의 장단점 이해) 본문

카테고리 없음

1.5 DATABASE 서브쿼리 VS 스칼라쿼리 (각각의 장단점 이해)

코딩낙타 2022. 3. 24. 16:12

서브쿼리 VS 스칼라쿼리 (각각의 장단점 이해)

참고링크: https://ttend.tistory.com/619

 

SQL 기초] 서브쿼리(Sub Query) 개념

서브쿼리(Sub Query)는 SQL 문장의 하부 절에 쿼리문을 사용하는 것이다. 즉, 메인쿼리의 SELECT문 하부의 WHERE절이나 FROM절에서 사용되는 쿼리를 서브쿼리라고 한다. 쿼리 안에 쿼리가 포함된 상태라

ttend.tistory.com

서브쿼리 => SQL 문장의 하부절에 쿼리문을 사용하는 것

 SCOTT @ ORACLE > SELECT ename, sal FROM emp
  2     WHERE sal >
  3             (SELECT sal FROM emp WHERE ename='CLARK');
 
ENAME                       SAL
-------------------- ----------
JONES                      2975
BLAKE                      2850
SCOTT                      3000
KING                       5000
FORD                       3000

 

서브쿼리 주의사항

  • 연산자의 오른쪽에 위치해야한다.
  • 괄호로 묶어주어야한다.

서브쿼리의 위치에 따른 명칭

위치 명칭
SELECT 스칼라 서브쿼리
FROM 인라인 뷰
WHERE 서브쿼리

단일 행 서브쿼리(Single-Row Subquery)

  • 서브쿼리의 결과가 1개의 행만 출력
  • 단일 행 서브쿼리에서는 단일행 비교연사자인 =, <>, <, > 등의 연산자를 사용 가능
-- =연산자를 사용해서 이름이 smith인 직원과 같은 부서의 직원 조회
 
 SCOTT @ ORACLE > SELECT ename, deptno FROM emp
  2               WHERE deptno = (SELECT deptno FROM emp WHERE ename='SMITH');
 
ENAME                    DEPTNO
-------------------- ----------
SMITH                        20
JONES                        20
SCOTT                        20
ADAMS                        20
FORD                         20


-- ">" 연산자를 사용해서 이름이 clark인 직원의 급여보다 많은 직원 조회
 
 SCOTT @ ORACLE > SELECT ename, sal FROM emp WHERE ename='CLARK';
 
ENAME                       SAL
-------------------- ----------
CLARK                      2450
 
 
 SCOTT @ ORACLE > SELECT ename, sal FROM emp
  2     WHERE sal > (SELECT sal FROM emp WHERE ename='CLARK');
 
ENAME                       SAL
-------------------- ----------
JONES                      2975
BLAKE                      2850
SCOTT                      3000
KING                       5000
FORD                       3000

다중 행 서브쿼리(Multiple-Row Subquery)

서브쿼리의 결과가 여러 건 출력

 

다중 행 서브쿼리에서 사용할 수 있는 다중행 비교 연산자들
IN 값은 값을 찾음 =와 같은 역할
서브쿼리의 반환이 1행 이상일 때 그 행들의 값을 반환
> ANY 최솟값을 반환
< ALL 최솟값을 반환
< ANY 최댓값을 반환
> ALL 최댓값을 반환
EXIST 서브쿼리 값이 있을 경우 반환
최솟값, 최대값의 의미보다는 등호(<, >)의 위치가 더 중요
> ANY는 이후 뒤 따라 나오는 서브쿼리의 여러 값 중에서 어느 값보다 큰 값을 의미
< ALL은 뒤의 서브쿼리의 모든 값보다 작은 값을 의미

 

-- job이 president인 사람과 같은 부서에 근무하는 사람을 조회
 
 SCOTT @ ORACLE > SELECT ename, job, deptno FROM emp
  2                 WHERE deptno
  3                 IN (SELECT deptno FROM emp WHERE job='PRESIDENT');
 
ENAME                JOB                    DEPTNO
-------------------- ------------------ ----------
MILLER               CLERK                      10
KING                 PRESIDENT                  10
CLARK                MANAGER                    10

최솟값, 최대값의 의미보다는 등호(<, >)의 위치가 더 중요

-- > ANY는 이후 뒤 따라 나오는 서브쿼리의 여러 값 중에서 어느 값보다 큰 값을 의미
-- < ALL은 뒤의 서브쿼리의 모든 값보다 작은 값을 의미

SCOTT @ ORACLE > SELECT ename, sal FROM emp WHERE job='SALESMAN';
 
ENAME                       SAL
-------------------- ----------
ALLEN                      1600
WARD                       1250
MARTIN                     1250
TURNER                     1500
 
 
 SCOTT @ ORACLE > SELECT ename, sal FROM emp
  2     WHERE sal > ANY(SELECT sal FROM emp WHERE job='SALESMAN');
 
ENAME                       SAL
-------------------- ----------
KING                       5000
FORD                       3000
SCOTT                      3000
JONES                      2975
BLAKE                      2850
CLARK                      2450
ALLEN                      1600
TURNER                     1500
MILLER                     1300
 
9 개의 행이 선택되었습니다.
 
 
 SCOTT @ ORACLE > SELECT ename, sal FROM emp
  2     WHERE sal < ALL(SELECT sal FROM emp WHERE job='SALESMAN');
 
ENAME                       SAL
-------------------- ----------
ADAMS                      1100
JAMES                       950
SMITH                       800

 

다중 컬럼 서브쿼리(Multi-Column Subquery)

  • 서브쿼리의 결과가 여러 칼럼을 출력
  • 메인쿼리 WHERE절과 서브쿼리에서 반환하는 컬럼의 수가 반드시 같아야만 함
-- 부서별로 가장 작은 급여(sal)를 받는 직원을 조회
 
 SCOTT @ ORACLE > SELECT deptno, ename, sal FROM emp
  2               WHERE (deptno, sal) IN
  3                       (SELECT deptno, MIN(sal) FROM emp GROUP BY deptno)
  4               ORDER BY deptno;
 
    DEPTNO ENAME                       SAL
---------- -------------------- ----------
        10 MILLER                     1300
        20 SMITH                       800
        30 JAMES                       950

스칼라 서브쿼리(Scala Subquery)

  • SQL에서 단일값을 스칼라값
  • 스칼라 서브쿼리는 SELECT절에 오는 서브쿼리로 결과값으로 1행만 반환
-- 직업이 ‘MANAGER’인 사원의 사원명, 부서명, job을 조회
-- SELECT문 안에 SELECT문이 스칼라 서브쿼리로 사용.
 
 
 SCOTT @ ORACLE > SELECT ename,
  2                          (SELECT dname FROM dept d 
                                WHERE d.deptno = e.deptno) dname, job
  3                FROM emp e
  4                WHERE job ='MANAGER';
 
ENAME                DNAME                        JOB
-------------------- ---------------------------- ------------------
JONES                RESEARCH                     MANAGER
BLAKE                SALES                        MANAGER
CLARK                ACCOUNTING                   MANAGER

 

상호연관 서브쿼리(Correlated Subquery)

  • 상호관련 서브쿼리라고도 칭함
  • 메인쿼리의 값을 서브쿼리에 주고 서브쿼리를 수행한 다음 그 결과를 다시 메인쿼리로 반환해서 수행하는 쿼리
 SCOTT @ ORACLE > SELECT ename, sal, deptno FROM emp ORDER BY deptno, sal;
 
ENAME                       SAL     DEPTNO
-------------------- ---------- ----------
MILLER                     1300         10
CLARK                      2450         10
KING                       5000         10
SMITH                       800         20
ADAMS                      1100         20
JONES                      2975         20
SCOTT                      3000         20
FORD                       3000         20
JAMES                       950         30
MARTIN                     1250         30
WARD                       1250         30
TURNER                     1500         30
ALLEN                      1600         30
BLAKE                      2850         30
 
14 개의 행이 선택되었습니다.
 
 
-- 부서별 평균 sal
 
 SCOTT @ ORACLE > SELECT deptno, AVG(sal) FROM emp GROUP BY deptno;
 
    DEPTNO   AVG(SAL)
---------- ----------
        30 1566.66667
        20       2175
        10 2916.66667
 
 
 
 
 
 SCOTT @ ORACLE > SELECT ename, deptno, sal
  2  FROM emp e1
  3  WHERE sal > (SELECT AVG(sal)
  4             FROM emp e2
  5             WHERE e2.deptno=e1.deptno)
  6  ORDER BY deptno;
 
ENAME                    DEPTNO        SAL
-------------------- ---------- ----------
KING                         10       5000
JONES                        20       2975
SCOTT                        20       3000
FORD                         20       3000
ALLEN                        30       1600
BLAKE                        30       2850
 
6 개의 행이 선택되었습니다.
 
 
-- 1) 메인쿼리에서 부서번호(e1.deptno)를 읽어서 서브쿼리로 전달
-- 2) 서브쿼리는 메인쿼리에서 받은 부서번호로 평균 급여 계산
-- 3) 다시 메인쿼리는 서브쿼리의 평균 급여보다 큰 급여의 직원 출력