2021년 10월 24일 일요일

오라클 SQL, 서브쿼리, 스칼라 서브쿼리(scalar subquery)

 

오라클 SQL, 서브쿼리, 스칼라 서브쿼리(scalar subquery)


오라클 9i에서 도입된 스칼라 서브쿼리scalar subquery는 하나의 단일 값이 출현할 수 있는 자리에 사용하는 서브 쿼리로 거의 모든 위치에서 사용할 수 있습니다. 다음은 스칼라 서브쿼리를 사용할 수 있는 곳 입니다.  만약 스칼라 서브 쿼리가 행을 반환하지 못하면 출력에 NULL 값을 사용하며 GROUP BY 절에서는 사용할 수 없습니다.


SELECT 문

CASE 표현식

INSERT 문의 VALUES 절

WHERE 절

ORDER BY 절

함수의 매개 변수


하나의 단일값을 선택하기 때문에 반드시 단일 값을 반환해야 합니다.


SELECT절의 컬럼 위치에  사용되는 경우 데이터 건수가 적을 때 조인 방식보다 유리합니다. 


다음은 부서별 사원수를 스칼라 서브쿼리로 구하는 예문 입니다.



부서(DEPT) 테이블의 행들을 하나씩 읽으면서 부서코드(DEPTNO), 부서명(DNAME)을 출력하고 그 행의 부서코드 값을 안쪽 서브쿼리에 넣어 서브 쿼리를 실행하여 해당 직원이 속한 부서의 사원수를 COUNT 합니다.


위의 쿼리를 인라인뷰, 조인을 이용하여 다시 작성하면 다음과 같습니다.



부서(DEPT) 테이블에는 40번 부서가 있지만 직원(EMP) 테이블에는 40번 부서원이 없으므로 인라인뷰 서브쿼리의 결과에서는 40번 부서가 없습니다.  그 결과와 DEPT 테이블이 조인을 하므로 40번 부서는 조회되지 않습니다.


5.5.1 직원 정보 추출하기 : 조인


조인을 이용하려면 양쪽 테이블에 조인키에 해당하는 컬럼이 있어야 합니다.조인은 조건이 양쪽 테이블 모두에서 정확히 일치하는 데이터만 추출됩니다. 조인을 사용하여 직원 정보를 추출해봅시다.


직원 테이블과 부서 테이블을 조인하여 사번, 직원명, 부서코드, 부서명을 추출합니다. 


SELECT EMPNO

             , ENAME

             , EMP.DEPTNO

             , DNAME

FROM    EMP, DEPT

WHERE EMP.DEPTNO = DEPT.DEPTNO;


<실행 결과>

 

    EMPNO

ENAME

    DEPTNO

JOB

1

      7782

CLARK

          10

ACCOUNTING

2

      7934

MILLER

          10

ACCOUNTING

3

      7788

SCOTT

          20

RESEARCH

…..

…...

…...

…...

…...

13

7521

WARD

        30



부서명은 EMP 테이블에 없고 DEPT 테이블에 있습니다. 부서명을 얻기 위해 ❶에서부서코드 DEPTNO 컬럼을 조인키로 사용합니다. EMP 테이블에서 부서코드(DEPTNO)가 NULL인 KING 직원은 출력되지 않습니다. 



5.5.2 직원 정보 추출하기 : 스칼라 서브쿼리


위 쿼리를 스칼라 서브쿼리를 사용해서 수정 합시다.


 스칼라 서브쿼리는 SELECT되는 행이 없을 때 NULL을 출력으로 합니다. 그래서 부서코드가 NULL인 “KING” 직원은 부서명이 NULL로출력됩니다. 


아래 쿼리는 EMP 테이블의 전체 데이터가 기본적으로 출력됩니다.


SELECT EMPNO

             , ENAME

             , DEPTNO

             , (SELECT DNAME FROM DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO)

FROM    EMP;


<실행 결과>

 

    EMPNO

ENAME

    DEPTNO

JOB

1

7369

SMITH

20

RESEARCH

2

7499

ALLEN

30

SALES

3

7521

WARD

30

SALES

4

7566

JONES

20

RESEARCH

5

7654

MARTIN

30

SALES

6

7698

BLAKE

30

SALES

7

7782

CLARK

10

ACCOUNTING

8

7788

SCOTT

20

RESEARCH

9

7839

KING

(null)

(null)

10

7844

TURNER

30

SALES

11

7876

ADAMS

20

RESEARCH

12

7900

JAMES

30

SALES

13

7902

FORD

20

RESEARCH

14

7934

MILLER

10

ACCOUNTING



5.5.3 부서별 직원 수 출력하기 : XXX


부서별로 직원 수를 출력해보겠습니다. 부서 직원 수가 NULL이면 0으로 대체하는 NVL() 함수를 사용하세요.


SELECT DEPTNO

             , DNAME

             , (SELECT ❶NVL(COUNT(*),0) FROM EMP 

                WHERE EMP.DEPTNO = DEPT.DEPTNO)  AS EMP_CNT

 FROM DEPT;   


<실행 결과>

 

    DEPTNO

DNAME

    EMPCNT

1

10

ACCOUNTING

2

2

20

RESEARCH

5

3

30

SALES

6

4

40

OPERATIONS

0


❶ NVL() 함수로 COUNT(*) 결과가 NULL이면 0으로 대체합니다. 

DEPT 테이블의 행들을 하나씩 읽어들이면서 읽은 DEPTNO 값을 서브쿼리에 넣어 EMP 테이블에서 해당 부서원들의 수를  카운트 하여 결과를 반환합니다. 이러한 스칼라 서브쿼리 는 DEPT 테이블의 건수가 아주 많다면 성능상 좋지 않을 수 있지만 건수가 얼마 되지 않는 다면 조인보다 성능이 좋을 수 있습니다.


5.5.4 INSERT절에 서브쿼리 사용하기 : 스칼라 서브쿼리



INSERT 절에 스칼라 서브쿼리를 사용한 예문입니다.


CREATE TABLE EMP_SUMMARY ( ❶

   SUM_SAL NUMBER,

   AVG_SAL NUMBER,

   MAX_SAL NUMBER,

   MIN_SAL NUMBER

);


INSERT INTO EMP_SUMMARY (

          SUM_SAL ,

          AVG_SAL ,

          MAX_SAL ,

          MIN_SAL )

   VALUES (

            (SELECT SUM(SAL) FROM EMP),

            (SELECT ROUND(AVG(SAL), 0) FROM EMP),

            (SELECT MAX(SAL) FROM EMP),

            (SELECT MIN(SAL) FROM EMP)

          );

          

COMMIT;


SELECT * FROM EMP_SUMMARY ;



<실행 결과>

 

    SUM_SAL

    AVG_SAL

    MAX_SAL

  MIN_SAL

1

29025

2073

5000

800

 

❶ 4개의 컬럼을 가지는  EMP_SUMMARY 테이블을 생성 합니다.

❷ INSERT절의 VALUES구에서 스칼라 서브쿼리를 사용하여 단일 값을 조회하여 삽입 합니다.

 

#오라클 #SQL #서부쿼리 #스칼라서브쿼리

댓글 없음:

댓글 쓰기

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...