본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Playdata_study/SQL.Oracle

210524 _DB3 (SQL) / 분석함수, JOIN

by 케리's 2021. 5. 24.

 

✨ 분석함수 종류를 살펴보고 활용하자.
✨  join 또는 subquery를 살펴보고 구현해보자.

 

 

분석함수

 

분석함수를 사용하는 이유

 : RDB상에서 컬럼과 컬럼연산, 비교, 연결은 쉬운반면 행과 행간의 관계를 정의하거나, 비교, 연산하는 것을 하나의 SQL로 처리하기 힘든점

 

프로그램 작성, 인라인 뷰를 이용해서 복잡한 SQL문 작성
분석함수를 도입해서 행간의 연산을 원활하게 연동한다. 중첩해서 사용하지 못하지만 서브 쿼리에서 사용할 수 있다.

 

 

[형식]

  SELECT Analytic_Function(arguments) OVER
  ([PARTITION BY 절] [ORDER BY 절] [Windowing 절] 중 택1)
  FROM 테이블명;

 


✔ Analytic_Fungtion( ) 

    : avg, count, lag, lead, max, min, rank, ratio_to_report, row_number, sum

 

    arguments 0~3 개 까지만 올 수 있다.
    count(*)만 허용 *, DISTINCT 는 해당 집계 함수가 허용할 때만 지원해준다.

 

 

✔ PARTITION BY 

   : 쿼리 결과를 <expr_list> 별로 그룹핑한다.

    생략시에는 하나의 그룹으로 리턴.

 

 

 

✔ ORDER BY

  : ORDER BY <expr_list> [ ASC | DESC | NULLS FIRST | NULLS LAST ]
    표현식에서는 별칭이나 숫자를 사용할 수 없다.

 

 


✔ Windowing 

 

  : ROWS는 물리적인 단위 (ROW위치) , RANGE 는 논리적인단위 (ROW의 값) 이다.


   ROWS [RANGE] BETWEEN start_point AND end_point
     → start_point : 그룹별 시작점을 의미
                         UNBOUNDED PRECEDING, CURRENT ROW
                         value_expr PRECEDING or value_expr FOLLOWING 이 올 수 있다.

 

    → end_point : 그룹별 시작점을 의미
                       UNBOUNDED FOLLOWING, CURRENT ROW
                       value_expr PRECEDING or value_expr FOLLOWING 이 올 수 있다.


✔ OVER

 

   : 해당 함수가 쿼리 결과 집합에 따라서 적용되는 지시어 이다.


     FROM, WHERE, GROUP BY, HAVING 이후에 계산된다.
     SELECT, ORDER BY 구문 뒤에 사용할 수 있다.

 

 

분석 함수 장점


 ✔ JOIN 이나 프로그램의 OVER HEAD를 줄임

   : QUERY SPEED의 향상된 SELF-JOIN, 절차적 로직으로 표현하는 것을
   NATIVE SQL 에서 바로 적용 할 수 있도록 JOIN 이나 프로그램의 OVER HEAD를 줄임

간결한 SQL로 복잡한 분석 작업을 수행이 가능

  : 유지보수가 간편하고 생산성 향상


이해 및 활용이 용이

  : 기존 SQL - syntax를 그래도 쓰기 때문에 ANSI SQL로 채택된다.

 

 

Ranking Family 특징


 대상 집합에 대해서 특정 칼럼들을 기준으로 순위나 등급을 부여한다.
 오름차순, 내림차순 가능
 NULL은 순위의 가장 처음 또는 마지막으로 강제 처리된다.
 RANK function 은 각 PARTITION 마다 초기화가 된다.
 순위 또는 등급은 GROUP BY, CUBE, ROLLUP 절 마다 초기화가 된다.

 

 

Q1)

 

  □ RANK ( ) : 각 ROW 마다 순위를 매긴다.

   PARTITION → ORDER BY → 1부터 시작하여 동일한 값은 동일한 순위를 가지고,
   동일한 순위의 수만큼 다음 순위는 건너 뛴다.

 

 

 # 사원테이블에서 사원의 이름, 부서번호, 급여, 급여가 많은 사원으로 부터 순위를 조회하자.

 

  SELECT ENAME, DEPTNO, SAL,
  RANK() OVER(ORDER BY SAL DESC) "RANK"
  FROM EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  RANK() OVER(ORDER BY SAL DESC) "RANK"
  3  FROM EMP;

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
KING                     10  5000     1
FORD                     20  3000     2
JONES                    20  2975     3
BLAKE                    30  2850     4
CLARK                    10  2450     5
ALLEN                    30  1600     6
TURNER                   30  1500     7
MILLER                   10  1300     8
MARTIN                   30  1250     9
WARD                     30  1250     9
JAMES                    30   950    11

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
SMITH                    20   800    12

12 rows selected.

 

 

  SELECT ENAME, DEPTNO, SAL,
  RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
  FROM EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
  3  FROM EMP;

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
KING                     10  5000     1
CLARK                    10  2450     2
MILLER                   10  1300     3 
FORD                     20  3000     1 # ← 쿼리결과를 DEPTNO 별로 그룹핑
JONES                    20  2975     2
SMITH                    20   800     3
BLAKE                    30  2850     1
ALLEN                    30  1600     2
TURNER                   30  1500     3
WARD                     30  1250     4
MARTIN                   30  1250     4

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
JAMES                    30   950     6

12 rows selected.

SQL>

 

 

Q2) 

 

□ 샘플 테이블 생성

  : 칼럼명을 명시하면 1:1로 VALUES 값을 줘야한다.

 

 CREATE TABLE TEST_EMP
 AS
 SELECT * FROM EMP;

INSERT INTO TEST_EMP (EMPNO, ENAME, SAL, DEPTNO) VALUES(111, 111, 3000, 30);
INSERT INTO TEST_EMP (EMPNO, ENAME, SAL, DEPTNO) VALUES(222, 222, 3000, 30);
INSERT INTO TEST_EMP (EMPNO, ENAME, SAL, DEPTNO) VALUES(333, 333, 3000, 20);
INSERT INTO TEST_EMP (EMPNO, ENAME, SAL, DEPTNO) VALUES(444, 444, 3000, 20);

 

SQL> SELECT *
  2  FROM TEST_EMP;

EMPNO ENAME                JOB                  MGR HIREDATE   SAL  COMM DEPTNO
----- -------------------- ------------------ ----- -------- ----- ----- ------
 7369 SMITH                CLERK               7902 80/12/17   800           20
 7499 ALLEN                SALESMAN            7698 81/02/20  1600   300     30
 7521 WARD                 SALESMAN            7698 81/02/22  1250   500     30
 7566 JONES                MANAGER             7839 81/04/02  2975           20
 7654 MARTIN               SALESMAN            7698 81/09/28  1250  1400     30
 7698 BLAKE                MANAGER             7839 81/05/01  2850           30
 7782 CLARK                MANAGER             7839 81/06/09  2450           10
 7839 KING                 PRESIDENT                81/11/17  5000           10
 7844 TURNER               SALESMAN            7698 81/09/08  1500     0     30
 7900 JAMES                CLERK               7698 81/12/03   950           30
 7902 FORD                 ANALYST             7566 81/12/03  3000           20

EMPNO ENAME                JOB                  MGR HIREDATE   SAL  COMM DEPTNO
----- -------------------- ------------------ ----- -------- ----- ----- ------
 7934 MILLER               CLERK               7782 82/01/23  1300           10
  111 111                                                     3000           30 #★
  222 222                                                     3000           30 #★
  333 333                                                     3000           20 #★
  444 444                                                     3000           20 #★

16 rows selected.

 

😎 알고가기

 

  COMMIT;  →  INSERT, DELETE, UPDATE 명령을 수행 후 저장

 

 

Q3) 

 

□ 샘플 테이블 생성 후 생성 테이블 RANK () 조회 

 

 SELECT ENAME, DEPTNO, SAL,
 RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
 FROM TEST_EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
  3  FROM TEST_EMP;

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
KING                     10  5000     1
CLARK                    10  2450     2
MILLER                   10  1300     3
444                      20  3000     1 # ===========
333                      20  3000     1
FORD                     20  3000     1
JONES                    20  2975     4
SMITH                    20   800     5
111                      30  3000     1 # ===========
222                      30  3000     1
BLAKE                    30  2850     3

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
ALLEN                    30  1600     4
TURNER                   30  1500     5
MARTIN                   30  1250     6
WARD                     30  1250     6
JAMES                    30   950     8
777                                   1

17 rows selected.

 

 

Q4)


□ DENSE_RANK( ) : 동률순위

  SELECT ENAME, DEPTNO, SAL,
  DENSE_RANK() OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
  FROM TEST_EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  DENSE_RANK() OVER(PARTITION BY DEPTNO ORDER BY SAL DESC) "RANK"
  3  FROM TEST_EMP;

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
KING                     10  5000     1
CLARK                    10  2450     2
MILLER                   10  1300     3
444                      20  3000     1 # ==== 동률순위=======
333                      20  3000     1 # ==== 동률순위=======
FORD                     20  3000     1 # ==== 동률순위=======
JONES                    20  2975     2 
SMITH                    20   800     3
111                      30  3000     1
222                      30  3000     1
BLAKE                    30  2850     2

ENAME                DEPTNO   SAL  RANK
-------------------- ------ ----- -----
ALLEN                    30  1600     3
TURNER                   30  1500     4
MARTIN                   30  1250     5
WARD                     30  1250     5
JAMES                    30   950     6
777                                   1

17 rows selected.

SQL>

 

 

Q5)

 

 □ CUME_DIST() : Cumulative Distribution Funtion ,

   : 주어진 그룹에 대한 상대적인 누적분포도 값을 반환

 

  - PARTITION 나누어진 블럭별로 각 row를 ORDER BY 절에 명시된 순서대로 정렬한 후

    그룹별 상대적인 위치 (누적된 분산정보)를 구한다.
  - 상대적인 위치는 구하고자 하는 값보다 작거나 같은 값을 가진 ROW수를

    그룹 내 전체 ROW수 로 나눈것을 의미한다. 결과 값의 범위는 0보다 크고 1보다 작거나 같다.

 

 

   # 20번 사원의 이름, 봉급, 누적분산 정보를 조회하자.


  SELECT ENAME, SAL, CUME_DIST() OVER (ORDER BY SAL)
  FROM TEST_EMP
  WHERE DEPTNO = 20;

 

SQL> SELECT ENAME, SAL, CUME_DIST() OVER(ORDER BY SAL)
  2  FROM TEST_EMP
  3  WHERE DEPTNO = 20;

ENAME                       SAL CUME_DIST()OVER(ORDERBYSAL)
-------------------- ---------- ---------------------------
SMITH                       800                          .2
JONES                      2975                          .4
333                        3000                           1
444                        3000                           1
FORD                       3000                           1

 

 

 # TEST_EMP 테이블에 있는 사원의 이름, 봉급, 누적분산 정보 조회

 

SQL> SELECT ENAME, SAL, CUME_DIST() OVER(ORDER BY SAL)
  2  FROM TEST_EMP;

ENAME                  SAL CUME_DIST()OVER(ORDERBYSAL)
-------------------- ----- ---------------------------
SMITH                  800                       .0588
JAMES                  950                       .1176
WARD                  1250                       .2353
MARTIN                1250                       .2353
MILLER                1300                       .2941
TURNER                1500                       .3529
ALLEN                 1600                       .4118
CLARK                 2450                       .4706
BLAKE                 2850                       .5294
JONES                 2975                       .5882
FORD                  3000                       .8824

ENAME                  SAL CUME_DIST()OVER(ORDERBYSAL)
-------------------- ----- ---------------------------
444                   3000                       .8824
111                   3000                       .8824
222                   3000                       .8824
333                   3000                       .8824
KING                  5000                       .9412
777                                                  1

17 rows selected.

 

Q6)

 

  □ NTILE()

  : 정확하게 떨어지지 않을 경우 근사치로 배분한 후 남는 값에 대해서 최초 PARTITION 부터 한개씩 배분한다.

 


 📎 PARTITION 내에 100개의 ROW 가 있다.

   4개의 BUCKET 값을 나누고 싶다. → NTILE(4)
  👉 1개의 BUCKET 25개씩 ROW가 배정된다.

 

 

 📎 PARTITION 내에 103개의 ROW 가 있다.

   5개의 BUCKET 값을 나누고 싶다 → NTILE(5)

   정확하게 떨어지지 않는 경우로, 근사치 배분 후 남는 값은 최초 PARTITION 으로 부터 한개 씩 배분 한다.
   👉 1 (21), 2(21), 3(21), 4(20), 5(2)

 


  # 사원의 봉급을 기준으로 4등급으로 분류하자.

 

  SELECT ENAME, SAL, NTILE(4) OVER(ORDER BY SAL)
  FROM EMP;

 

SQL> SELECT ENAME, SAL, NTILE(4) OVER(ORDER BY SAL)
  2  FROM EMP;

ENAME                  SAL NTILE(4)OVER(ORDERBYSAL)
-------------------- ----- ------------------------
SMITH                  800                        1
JAMES                  950                        1
WARD                  1250                        1
MARTIN                1250                        2
MILLER                1300                        2
TURNER                1500                        2
ALLEN                 1600                        3
CLARK                 2450                        3
BLAKE                 2850                        3
JONES                 2975                        4
FORD                  3000                        4

ENAME                  SAL NTILE(4)OVER(ORDERBYSAL)
-------------------- ----- ------------------------
KING                  5000                        4

12 rows selected.

 


Q7)

 

  □ ROW_NUMBER()
  : PARTITION 내에 ORDER BY 절에 의해 정렬된 순서로 유일한 값을 리턴한다.
    ROWNUM과는 전혀 상관없다.

  # 사원번호, 이름, 봉급, 입사일을 조회하는데 순번을 매기자 (ROW_NUMBER())
     급여가 많은 순으로 같은 급여를 받는 경우 입사일이 빠른 사람부터 순번을 부여하자.

 


  SELECT EMPNO, ENAME, SAL, HIREDATE,
  ROW_NUMBER() OVER (ORDER BY SAL DESC, HIREDATE ASC) AS 순번
  FROM TEST_EMP;

 

SQL> SELECT EMPNO, ENAME, SAL, HIREDATE,
  2   ROW_NUMBER() OVER (ORDER BY SAL DESC, HIREDATE ASC) AS 순번
  3   FROM TEST_EMP;

EMPNO ENAME                  SAL HIREDATE  순번
----- -------------------- ----- -------- -----
 7839 KING                  5000 81/11/17     1
 7902 FORD                  3000 81/12/03     2
  333 333                   3000              3
  444 444                   3000              4
  222 222                   3000              5
  111 111                   3000              6
 7566 JONES                 2975 81/04/02     7
 7698 BLAKE                 2850 81/05/01     8
 7782 CLARK                 2450 81/06/09     9
 7499 ALLEN                 1600 81/02/20    10
 7844 TURNER                1500 81/09/08    11

EMPNO ENAME                  SAL HIREDATE  순번
----- -------------------- ----- -------- -----
 7934 MILLER                1300 82/01/23    12
 7521 WARD                  1250 81/02/22    13
 7654 MARTIN                1250 81/09/28    14
 7900 JAMES                  950 81/12/03    15
 7369 SMITH                  800 80/12/17    16

16 rows selected.

 

 

Q8)

 

  □ Windowing ()

  : 윈도우 집계함수 (sum, min, max, min) 는 ROW에 대한 집계 함수

  REPORTING

  : 한 집합 레벨에 대한 집계 값과 다른 집합 레벨에 대한 집계 값의 비교를 통해 분석하고자 하는 경우

   ex) 사원의 급여와 해당 부서의 평균 급여를 비교할때, 사원의 급여를 제외한 부서의 평균 급여를 알고 싶다.

 


  # 사원의 이름, 부서번호, 급여, 전체급여 합계, 부서별 합계를 리턴하자.


 SELECT ENAME, DEPTNO, SAL,
 SUM(SAL) OVER() "TOTAL_SUM",
 SUM(SAL) OVER(PARTITION BY DEPTNO) "DEPT_SUM"
 FROM TEST_EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  SUM(SAL) OVER() "TOTAL_SUM",
  3  SUM(SAL) OVER(PARTITION BY DEPTNO) "DEPT_SUM"
  4  FROM TEST_EMP;

ENAME                DEPTNO   SAL TOTAL_SUM DEPT_SUM
-------------------- ------ ----- --------- --------
CLARK                    10  2450     36925     8750
MILLER                   10  1300     36925     8750
KING                     10  5000     36925     8750
333                      20  3000     36925    12775
SMITH                    20   800     36925    12775
FORD                     20  3000     36925    12775
444                      20  3000     36925    12775
JONES                    20  2975     36925    12775
222                      30  3000     36925    15400
111                      30  3000     36925    15400
JAMES                    30   950     36925    15400

ENAME                DEPTNO   SAL TOTAL_SUM DEPT_SUM
-------------------- ------ ----- --------- --------
TURNER                   30  1500     36925    15400
BLAKE                    30  2850     36925    15400
MARTIN                   30  1250     36925    15400
WARD                     30  1250     36925    15400
ALLEN                    30  1600     36925    15400
777                                   36925

17 rows selected.


Q9)

 

 # 사원의 이름, 부서번호, 급여, 업무별 급여평균, 해당업무의 최대급여를 조회한다.

 

  SELECT ENAME, DEPTNO, SAL,
  AVG(SAL) OVER (PARTITION BY JOB) "AVG_SUM",
  MAX(SAL) OVER (PARTITION BY JOB) "MAX_SUM"
  FROM TEST_EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  AVG(SAL) OVER (PARTITION BY JOB) "AVG_SUM",
  3  MAX(SAL) OVER (PARTITION BY JOB) "MAX_SUM"
  4  FROM TEST_EMP;

ENAME                DEPTNO   SAL AVG_SUM MAX_SUM
-------------------- ------ ----- ------- -------
FORD                     20  3000    3000    3000
JAMES                    30   950    1017    1300
SMITH                    20   800    1017    1300
MILLER                   10  1300    1017    1300
JONES                    20  2975    2758    2975
BLAKE                    30  2850    2758    2975
CLARK                    10  2450    2758    2975
KING                     10  5000    5000    5000
TURNER                   30  1500    1400    1600
MARTIN                   30  1250    1400    1600
WARD                     30  1250    1400    1600

ENAME                DEPTNO   SAL AVG_SUM MAX_SUM
-------------------- ------ ----- ------- -------
ALLEN                    30  1600    1400    1600
111                      30  3000    3000    3000
222                      30  3000    3000    3000
333                      20  3000    3000    3000
444                      20  3000    3000    3000
777                                  3000    3000

17 rows selected.


Q10)

 

  :  ROWS BETWEEN start_point AND end_point
     → start_point : 그룹별 시작점을 의미
                         UNBOUNDED PRECEDING, CURRENT ROW
                         value_expr PRECEDING or value_expr FOLLOWING 이 올 수 있다.

 

    → end_point : 그룹별 시작점을 의미
                       UNBOUNDED FOLLOWING, CURRENT ROW
                       value_expr PRECEDING or value_expr FOLLOWING 이 올 수 있다.

 

 

 

 # 사원이름, 부서번호, 봉급합계를 3줄씩 더한결과, 누적합계를 구해보자.

 SELECT ENAME, DEPTNO, SAL,
 SUM(SAL) OVER (ORDER BY SAL ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) "SUM1",
 SUM(SAL) OVER (ORDER BY SAL ROWS UNBOUNDED PRECEDING) "SUM 12"
 FROM TEST_EMP;

 

SQL> SELECT ENAME, DEPTNO, SAL,
  2  SUM(SAL) OVER(ORDER BY SAL ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) "SUM1",
  3  SUM(SAL) OVER(ORDER BY SAL ROWS UNBOUNDED PRECEDING) "SUM12"
  4  FROM TEST_EMP;

ENAME                DEPTNO   SAL  SUM1 SUM12
-------------------- ------ ----- ----- -----
SMITH                    20   800  1750   800
JAMES                    30   950  3000  1750
WARD                     30  1250  3450  3000
MARTIN                   30  1250  3800  4250
MILLER                   10  1300  4050  5550
TURNER                   30  1500  4400  7050
ALLEN                    30  1600  5550  8650
CLARK                    10  2450  6900 11100
BLAKE                    30  2850  8275 13950
JONES                    20  2975  8825 16925
FORD                     20  3000  8975 19925

ENAME                DEPTNO   SAL  SUM1 SUM12
-------------------- ------ ----- ----- -----
444                      20  3000  9000 22925
111                      30  3000  9000 25925
222                      30  3000  9000 28925
333                      20  3000 11000 31925
KING                     10  5000  8000 36925
777                                5000 36925

17 rows selected.



Q11)

 

 □ RATIO_TO_REPORT()

  : 해당 구간에서 차지하는 비율을 리턴하는 함수

 

  # 사원의 총 월급을 50000으로 증가했을 때,

    기존 월급 비율로 적용했을 경우 각 사원은 얼마씩 받게되는지 확인해보자.

  SELECT ENAME, SAL,
  RATIO_TO_REPORT(SAL) OVER() AS "비율",
  TRUNC(RATIO_TO_REPORT(SAL) OVER() * 50000) AS "받을 급여"
  FROM TEST_EMP;

 

SQL> SELECT ENAME, SAL,
  2  RATIO_TO_REPORT(SAL) OVER() AS "비율",
  3  TRUNC (RATIO_TO_REPORT(SAL) OVER() *50000) AS "받을 급여"
  4  FROM TEST_EMP;

ENAME                  SAL  비율 받을 급여
-------------------- ----- ----- ---------
SMITH                  800 .0217      1083
ALLEN                 1600 .0433      2166
WARD                  1250 .0339      1692
JONES                 2975 .0806      4028
MARTIN                1250 .0339      1692
BLAKE                 2850 .0772      3859
CLARK                 2450 .0664      3317
KING                  5000 .1354      6770
TURNER                1500 .0406      2031
JAMES                  950 .0257      1286
FORD                  3000 .0812      4062

ENAME                  SAL  비율 받을 급여
-------------------- ----- ----- ---------
MILLER                1300 .0352      1760
111                   3000 .0812      4062
222                   3000 .0812      4062
333                   3000 .0812      4062
444                   3000 .0812      4062
777

17 rows selected.

 



LEAD/LAG FAMILY

  : 특정 ROW가 속한 파티션 내에서 상대적 상/하 위치에 있는 특정 ROW의 컬럼값을 참조하거나
   상호 비교할 때 사용하는 함수.

 


Q12)

 

  □ LAG : 이전 로우의 값 반환

   : 파티션 내에서 OFFSET 에 지정된 값 (1) 만큼 상대적으로 상황에 위치한 ROW
   (오름차순 기준시 정렬 값 보다 작은 값을 갖는 로우, 내림차순 기준시 로우의 정렬값 보다 큰값을 갖는 로우) 를

   참조하기 위해 사용된다.

 

 

 # 사원이름, 부서번호, 봉급, 본인 이전의 봉급 값을 조회 

 

  SELECT ENAME, DEPTNO, SAL,
  LAG(SAL,1,0) OVER (ORDER BY SAL) AS NET_SAL,
  LAG(SAL,1,SAL) OVER (ORDER BY SAL) AS SAL2,
  LAG(SAL,1,SAL) OVER (PARTITION BY DEPTNO ORDER BY SAL) AS SAL3
  FROM TEST_EMP;

 

# LAG 함수의 인자값중 2번째 값을 1로 할 경우 1번째 이전값 리턴
# LAG 함수의 인자값중 3번째 값을 0으로 할 경우 이전값이 없을 경우 0을 리턴

SQL> SELECT ENAME, DEPTNO, SAL,
  2  LAG(SAL,1,0) OVER(ORDER BY SAL) AS NET_SAL,
  3  LAG(SAL,1,SAL) OVER(ORDER BY SAL) AS SAL2,
  4  LAG(SAL,1,SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL) AS SAL3
  5  FROM TEST_EMP;

ENAME                DEPTNO   SAL NET_SAL  SAL2  SAL3
-------------------- ------ ----- ------- ----- -----
SMITH                    20   800       0   800   800
JAMES                    30   950     800   800   950
MARTIN                   30  1250     950   950  1250
WARD                     30  1250    1250  1250   950
MILLER                   10  1300    1250  1250  1300
TURNER                   30  1500    1300  1300  1250
ALLEN                    30  1600    1500  1500  1500
CLARK                    10  2450    1600  1600  1300
BLAKE                    30  2850    2450  2450  1600
JONES                    20  2975    2850  2850   800
444                      20  3000    2975  2975  3000

ENAME                DEPTNO   SAL NET_SAL  SAL2  SAL3
-------------------- ------ ----- ------- ----- -----
FORD                     20  3000    3000  3000  2975
333                      20  3000    3000  3000  3000
111                      30  3000    3000  3000  2850
222                      30  3000    3000  3000  3000
KING                     10  5000    3000  3000  2450
777                                  5000  5000

17 rows selected.



Q13)

 

  □ LEAD () : 이후 로우의 값을 리턴 하는 함수 입니다 

   : 파티션 내에서 OFFSET 에 지정된 값 (1) 만큼 상대적으로 상황에 위치한 로우
     (오름차순 기준시 정렬 값 보다 큰 값을 갖는 로우, 내림차순 기준시 로우의 정렬값 보다 작은값을 갖는 로우)

    참조하기 위해 사용된다.

 

   # 사원이름, 부서번호, 봉급, 본인 이후의 봉급 값을 조회 LEAD

 


  SELECT ENAME, DEPTNO, SAL,
  LEAD(SAL,1,0) OVER (ORDER BY SAL) AS NET_SAL,
  LEAD(SAL,1,SAL) OVER (ORDER BY SAL) AS SAL2,
  LEAD(SAL,1,SAL) OVER (PARTITION BY DEPTNO ORDER BY SAL) AS SAL3
  FROM TEST_EMP;

 

 

# LEAD 함수의 인자값중 2번째 값을 1로 할 경우 1번째 이후 값 리턴
# LAG 함수의 인자값중 3번째 값을 0으로 할 경우 이후 값이 없을 경우 0을 리턴

SQL> SELECT ENAME, DEPTNO, SAL,
  2  LEAD(SAL,1,0) OVER (ORDER BY SAL) AS NET_SAL,
  3  LEAD(SAL,1,SAL) OVER (ORDER BY SAL) AS SAL2,
  4  LEAD(SAL,1,SAL) OVER (PARTITION BY DEPTNO ORDER BY SAL) AS SAL3
  5  FROM TEST_EMP;

ENAME                DEPTNO   SAL NET_SAL  SAL2  SAL3
-------------------- ------ ----- ------- ----- -----
SMITH                    20   800     950   950  2975
JAMES                    30   950    1250  1250  1250
MARTIN                   30  1250    1250  1250  1500
WARD                     30  1250    1300  1300  1250
MILLER                   10  1300    1500  1500  2450
TURNER                   30  1500    1600  1600  1600
ALLEN                    30  1600    2450  2450  2850
CLARK                    10  2450    2850  2850  5000
BLAKE                    30  2850    2975  2975  3000
JONES                    20  2975    3000  3000  3000
444                      20  3000    3000  3000  3000

ENAME                DEPTNO   SAL NET_SAL  SAL2  SAL3
-------------------- ------ ----- ------- ----- -----
FORD                     20  3000    3000  3000  3000
333                      20  3000    3000  3000  3000
111                      30  3000    3000  3000  3000
222                      30  3000    5000  5000  3000
KING                     10  5000                5000
777                                     0

17 rows selected.



JOIN

   :  데이터 베이스에서 여러 테이블의 데이터가 필요한 경우 사용한다.


   - 어떤 테이블을 기준으로 다른 테이블에있는 ROW를 찾아오는 것
   - 서로 독립적인 데이터들 간의 조인을 이용해서 필요한 정보를 참조하게 된다.
   - 해당열에 존재하는 공통 값, 일반적으로 기본키 및 외래키 열을 조인 조건으로 사용하여

     한 테이블의 행을 다른테이블의 행에 조인 할 수 있다.
   - N개의 테이블을 조인하려면 최소 N-1개의 조인 조건이 필요하다.
     만일 3개의 테이블을 조인하려면 최소 2개의 조인조건이 필요하다.

 

 


  [형식]  # 테이블 별칭 가능, 30자이내

 

  SELECT TABLE1.COLUMN, TABLE2.COLUMN , , , ,
  FROM TABLE1, TABLE2
  WHERE TABLE1.COLUMN = TABLE2.COLUMN;

 

 


 ✔ JOIN = INNER JOIN = EQUIJOIN

      : 두개의 테이블 간의 컬럼 값들이 정확하게 일치하는 경우 테이터를 리턴

 

 ✔ OUTER JOIN 

      : 주/종관계를 만들어서 주 테이블은 전체출력, 종테이블은 TRUE만 출력 한다.

 

 ✔ SELF JOIN

     : 같은 테이블에 있는 행들을 JOIN하는데 사용한다.


 ✔ NON-EQUIJOIN

    : 두 개의 테이블 간에 컬럼 값들이 정확하게 일치하지 않는 경우 사용한다.


Q14)

 

□ Cartesian

    : 첫번 째 테이블의 모든 행이 두번째 모든 행에 조인

 

ex)

      A = ROW (N)
      B = ROW (M)
       →  M * N


 <조건없이 JOIN>
 SELECT *
 FROM EMP, DEPT;

SQL> SELECT *
  2  FROM EMP, DEPT;

EMPNO ENAME      JOB           MGR HIREDATE   SAL  COMM DEPTNO DEPTNO
----- ---------- ----------- ----- -------- ----- ----- ------ ------
DNAME       LOC
----------- --------------------------
 7369 SMITH      CLERK        7902 80/12/17   800           20     10
ACCOUNTING  NEW YORK

 7499 ALLEN      SALESMAN     7698 81/02/20  1600   300     30     10
ACCOUNTING  NEW YORK

 7521 WARD       SALESMAN     7698 81/02/22  1250   500     30     10
ACCOUNTING  NEW YORK


EMPNO ENAME      JOB           MGR HIREDATE   SAL  COMM DEPTNO DEPTNO
----- ---------- ----------- ----- -------- ----- ----- ------ ------
DNAME       LOC
----------- --------------------------
 7566 JONES      MANAGER      7839 81/04/02  2975           20     10
ACCOUNTING  NEW YORK

 7654 MARTIN     SALESMAN     7698 81/09/28  1250  1400     30     10
ACCOUNTING  NEW YORK

 7698 BLAKE      MANAGER      7839 81/05/01  2850           30     10
ACCOUNTING  NEW YORK


EMPNO ENAME      JOB           MGR HIREDATE   SAL  COMM DEPTNO DEPTNO
----- ---------- ----------- ----- -------- ----- ----- ------ ------
DNAME       LOC
----------- --------------------------
 7782 CLARK      MANAGER      7839 81/06/09  2450           10     10
ACCOUNTING  NEW YORK

 7839 KING       PRESIDENT         81/11/17  5000           10     10
ACCOUNTING  NEW YORK

 7844 TURNER     SALESMAN     7698 81/09/08  1500     0     30     10
ACCOUNTING  NEW YORK


EMPNO ENAME      JOB           MGR HIREDATE   SAL  COMM DEPTNO DEPTNO
----- ---------- ----------- ----- -------- ----- ----- ------ ------
DNAME       LOC
----------- --------------------------
 7900 JAMES      CLERK        7698 81/12/03   950           30     10
ACCOUNTING  NEW YORK

 7902 FORD       ANALYST      7566 81/12/03  3000           20     10
ACCOUNTING  NEW YORK

 7934 MILLER     CLERK        7782 82/01/23  1300           10     10
ACCOUNTING  NEW YORK


EMPNO ENAME      JOB           MGR HIREDATE   SAL  COMM DEPTNO DEPTNO
----- ---------- ----------- ----- -------- ----- ----- ------ ------
DNAME       LOC
----------- --------------------------
 7369 SMITH      CLERK        7902 80/12/17   800           20     20
RESEARCH    DALLAS

 7499 ALLEN      SALESMAN     7698 81/02/20  1600   300     30     20
RESEARCH    DALLAS

 7521 WARD       SALESMAN     7698 81/02/22  1250   500     30     20
RESEARCH    DALLAS


 ' ' '

48 rows selected.



Q15)

 

  □ INNER JOIN (FALSE, NULL)을 제외, 맞는값만 나옴
 

  # INNER JOIN 을 이용하여 사원테이블의 사원번호, 이름, 부서번호, 부서명 조회해보자.

 


  <ANSI>

 

  SELECT EMPNO, ENAME, DEPTNO, DNAME
  FROM EMP JOIN DEPT USING(DEPTNO);

 

SQL> SELECT EMPNO, ENAME, DEPTNO, DNAME
  2  FROM EMP JOIN DEPT USING(DEPTNO);

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7839 KING           10 ACCOUNTING
 7782 CLARK          10 ACCOUNTING
 7934 MILLER         10 ACCOUNTING
 7902 FORD           20 RESEARCH
 7369 SMITH          20 RESEARCH
 7566 JONES          20 RESEARCH
 7900 JAMES          30 SALES
 7844 TURNER         30 SALES
 7654 MARTIN         30 SALES
 7521 WARD           30 SALES
 7499 ALLEN          30 SALES

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7698 BLAKE          30 SALES

12 rows selected.

 

  <ORACLE>

 

  SELECT TABLE1.COLUMN, TABLE2.COLUMN, , , ,
  FROM TABLE1, TABLE2
  WHERE TABLE1.COLUMN = TABLE2.COLUMN;


  SELECT E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
  FROM EMP E, DEPT D
  WHERE E.DEPTNO = D.DEPTNO;

SQL> SELECT E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
  2  FROM EMP E, DEPT D
  3  WHERE E.DEPTNO = D.DEPTNO;

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7839 KING           10 ACCOUNTING
 7782 CLARK          10 ACCOUNTING
 7934 MILLER         10 ACCOUNTING
 7902 FORD           20 RESEARCH
 7369 SMITH          20 RESEARCH
 7566 JONES          20 RESEARCH
 7900 JAMES          30 SALES
 7844 TURNER         30 SALES
 7654 MARTIN         30 SALES
 7521 WARD           30 SALES
 7499 ALLEN          30 SALES

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7698 BLAKE          30 SALES

12 rows selected.

 


Q16)

 

 # TEST_EMP 테이블에 부서 배치 받지 않은 사원을 추가해서 INNER JOIN 하자.
    INSERT INTO TEST_EMP(ENAME, DEPTNO) VALUES(999, NULL);

 <ANSI>


  SELECT EMPNO, ENAME, DEPTNO, DNAME
  FROM TEST_EMP JOIN DEPT USING(DEPTNO);

 

SQL> INSERT INTO TEST_EMP(ENAME, DEPTNO) VALUES(999,NULL);
1 row created.

## ↑ INNER JOIN은 컬럼값들이 정확하게 일치하는 경우만 데이터 리턴한다.
## 따라서 아래와 같이 JOIN 시, 999 값은 나오지 않는다. 

SQL> SELECT EMPNO, ENAME, DEPTNO, DNAME
  2  FROM TEST_EMP JOIN DEPT USING(DEPTNO);

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7782 CLARK          10 ACCOUNTING
 7934 MILLER         10 ACCOUNTING
 7839 KING           10 ACCOUNTING
 7566 JONES          20 RESEARCH
 7369 SMITH          20 RESEARCH
  333 333            20 RESEARCH
  444 444            20 RESEARCH
 7902 FORD           20 RESEARCH
 7844 TURNER         30 SALES
 7900 JAMES          30 SALES
  222 222            30 SALES

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7499 ALLEN          30 SALES
  111 111            30 SALES
 7521 WARD           30 SALES
 7654 MARTIN         30 SALES
 7698 BLAKE          30 SALES

16 rows selected.

 


  <ORACLE>


 SELECT T.EMPNO, T.ENAME, T.DEPTNO, D.DNAME
 FROM TEST_EMP T, DEPT D
 WHERE T.DEPTNO = D.DEPTNO;

 

SQL> SELECT T.EMPNO, T.ENAME, T.DEPTNO, D.DNAME
  2  FROM TEST_EMP T, DEPT D
  3  WHERE T.DEPTNO = D.DEPTNO;

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7782 CLARK          10 ACCOUNTING
 7934 MILLER         10 ACCOUNTING
 7839 KING           10 ACCOUNTING
 7566 JONES          20 RESEARCH
 7369 SMITH          20 RESEARCH
  333 333            20 RESEARCH
  444 444            20 RESEARCH
 7902 FORD           20 RESEARCH
 7844 TURNER         30 SALES
 7900 JAMES          30 SALES
  222 222            30 SALES

EMPNO ENAME      DEPTNO DNAME
----- ---------- ------ -----------
 7499 ALLEN          30 SALES
  111 111            30 SALES
 7521 WARD           30 SALES
 7654 MARTIN         30 SALES
 7698 BLAKE          30 SALES

16 rows selected.


Q17)

 

 # SALESMAN 의 사원번호, 이름, 급여, 부서명, 근무지를 리턴한다.

SELECT TABLE1.COLUMN, TABLE2.COLUMN, , , ,
FROM TABLE1, TABLE2
WHERE TABLE1.COLUMN = TABLE2.COLUMN;

 <ANSI>


  SELECT EMPNO, ENAME, SAL, DNAME, LOC
  FROM EMP JOIN DEPT USING(DEPTNO)
  WHERE JOB = 'SALESMAN';

 

SQL> SELECT EMPNO, ENAME, SAL, DNAME, LOC
  2  FROM EMP JOIN DEPT USING(DEPTNO)
  3  WHERE JOB = 'SALESMAN';

EMPNO ENAME        SAL DNAME       LOC
----- ---------- ----- ----------- --------------------------
 7499 ALLEN       1600 SALES       CHICAGO
 7521 WARD        1250 SALES       CHICAGO
 7654 MARTIN      1250 SALES       CHICAGO
 7844 TURNER      1500 SALES       CHICAGO



 <ORACLE>


 SELECT E.EMPNO, E.ENAME, E.SAL, D.DNAME, D.LOC
 FROM EMP E, DEPT D
 WHERE E.DEPTNO = D.DEPTNO AND E.JOB = 'SALESMAN';

 

SQL> SELECT E.EMPNO, E.ENAME, E.SAL, D.DNAME, D.LOC
  2  FROM EMP E, DEPT D
  3  WHERE E.DEPTNO = D.DEPTNO AND E.JOB = 'SALESMAN';

EMPNO ENAME        SAL DNAME       LOC
----- ---------- ----- ----------- --------------------------
 7499 ALLEN       1600 SALES       CHICAGO
 7521 WARD        1250 SALES       CHICAGO
 7654 MARTIN      1250 SALES       CHICAGO
 7844 TURNER      1500 SALES       CHICAGO

 


Q18 )

 

 □ OUTER JOIN

  : 주종관계를 만들어서 주 테이블은 전체출력, 종테이블은 TRUE만 출력

 


 # EMP 테이블()DEPT 테이블()에서

   EMP 테이블에 있는 모든 자료를 사원번호, 이름, 직업,
   DEPT 테이블의 부서번호 부서명을 조회하자.

 <ANSI>


 SELECT EMPNO, ENAME, JOB, DEPTNO, DNAME
 FROM EMP OUTER JOIN DEPT USING(DEPTNO);

 

SQL> SELECT EMPNO, ENAME, JOB, DEPTNO, DNAME
  2  FROM EMP OUTER JOIN DEPT USING(DEPTNO);

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7839 KING       PRESIDENT       10 ACCOUNTING
 7782 CLARK      MANAGER         10 ACCOUNTING
 7934 MILLER     CLERK           10 ACCOUNTING
 7902 FORD       ANALYST         20 RESEARCH
 7369 SMITH      CLERK           20 RESEARCH
 7566 JONES      MANAGER         20 RESEARCH
 7900 JAMES      CLERK           30 SALES
 7844 TURNER     SALESMAN        30 SALES
 7654 MARTIN     SALESMAN        30 SALES
 7521 WARD       SALESMAN        30 SALES
 7499 ALLEN      SALESMAN        30 SALES

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7698 BLAKE      MANAGER         30 SALES

12 rows selected.

 


 SELECT EMPNO, ENAME, JOB, DEPTNO, DNAME
 FROM EMP LEFT OUTER JOIN DEPT USING(DEPTNO);
            주                           종

 

SQL> SELECT EMPNO, ENAME, JOB, DEPTNO, DNAME
  2  FROM EMP LEFT OUTER JOIN DEPT USING(DEPTNO);

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7934 MILLER     CLERK           10 ACCOUNTING
 7839 KING       PRESIDENT       10 ACCOUNTING
 7782 CLARK      MANAGER         10 ACCOUNTING
 7902 FORD       ANALYST         20 RESEARCH
 7566 JONES      MANAGER         20 RESEARCH
 7369 SMITH      CLERK           20 RESEARCH
 7900 JAMES      CLERK           30 SALES
 7844 TURNER     SALESMAN        30 SALES
 7698 BLAKE      MANAGER         30 SALES
 7654 MARTIN     SALESMAN        30 SALES
 7521 WARD       SALESMAN        30 SALES

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7499 ALLEN      SALESMAN        30 SALES

12 rows selected.



<ORACLE>


 SELECT E.EMPNO, E.ENAME, E.JOB, D.DEPTNO, D.DNAME
 FROM DEPT D, EMP E
 WHERE D.DEPTNO = E.DEPTNO(+);

 

# LEFT OUTER JOIN // 왼쪽열을 기준으로 오른쪽 열의 데이터 존재 여부 상관없이 출력

SQL> SELECT E.EMPNO, E.ENAME, E.JOB, D.DEPTNO, D.DNAME
  2  FROM DEPT D, EMP E
  3  WHERE D.DEPTNO = E.DEPTNO(+);

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7839 KING       PRESIDENT       10 ACCOUNTING
 7782 CLARK      MANAGER         10 ACCOUNTING
 7934 MILLER     CLERK           10 ACCOUNTING
 7902 FORD       ANALYST         20 RESEARCH
 7369 SMITH      CLERK           20 RESEARCH
 7566 JONES      MANAGER         20 RESEARCH
 7900 JAMES      CLERK           30 SALES
 7844 TURNER     SALESMAN        30 SALES
 7654 MARTIN     SALESMAN        30 SALES
 7521 WARD       SALESMAN        30 SALES
 7499 ALLEN      SALESMAN        30 SALES

EMPNO ENAME      JOB         DEPTNO DNAME
----- ---------- ----------- ------ -----------
 7698 BLAKE      MANAGER         30 SALES
                                 40 OPERATIONS

13 rows selected.


❔ LEFT/RIGHT OUTER JOIN 

SELECT *
FROM X LEFT OUTER JOIN Y USING(S1); - 다 조회됨


SELECT *
FROM X RIGHT OUTER JOIN Y USING(S1); - 맞는 것만 조회됨

 

SQL> SELECT *
  2  FROM X LEFT OUTER JOIN Y USING(S1);

S1   X2   Y2
---- ---- ----
YA
YB   1    1
C

SQL> SELECT *
  2  FROM X RIGHT OUTER JOIN Y USING(S1);

S1   X2   Y2
---- ---- ----
YA
YB   1    1



Q19)

 

  □ SELF JOIN

   : ANCI 에는 SELF JOIN 이란 말이 없고, ORACLE SELF JOIN이라는 말이 있음

 

   # ○ 사원의 관리자는  이다.

 


<ORACLE>


 SELECT WORKER.ENAME || '사원의 관리자는' || MANAGER.ENAME || '이다' AS "관리자 정보"
 FROM EMP WORKER, EMP MANAGER
 WHERE WORKER.MGR = MANAGER.EMPNO

 

SQL> SELECT WORKER.ENAME ||'사원의 관리자는' ||MANAGER.ENAME ||'이다' AS "관리자 정보"
  2  FROM EMP WORKER, EMP MANAGER
  3  WHERE WORKER.MGR = MANAGER.EMPNO;

관리자 정보
--------------------------------------------------------------------------------
FORD사원의 관리자는JONES이다
JAMES사원의 관리자는BLAKE이다
TURNER사원의 관리자는BLAKE이다
WARD사원의 관리자는BLAKE이다
MARTIN사원의 관리자는BLAKE이다
ALLEN사원의 관리자는BLAKE이다
MILLER사원의 관리자는CLARK이다
CLARK사원의 관리자는KING이다
JONES사원의 관리자는KING이다
BLAKE사원의 관리자는KING이다
SMITH사원의 관리자는FORD이다

11 rows selected.


SELECT WORKER.ENAME || '사원의 관리자는' || MANAGER.ENAME || '이다' AS "관리자 정보"
FROM EMP WORKER, EMP MANAGER
WHERE WORKER.MGR = MANAGER.EMPNO(+); 

 

SQL> SELECT WORKER.ENAME || '사원의 관리자는' || MANAGER.ENAME || '이다' AS "관리자 정보"
  2  FROM EMP WORKER, EMP MANAGER
  3  WHERE WORKER.MGR = MANAGER.EMPNO(+); # LEFT(MGR) 의 모든것이 나옴

관리자 정보
--------------------------------------------------------------------------------
FORD사원의 관리자는JONES이다
JAMES사원의 관리자는BLAKE이다
TURNER사원의 관리자는BLAKE이다
MARTIN사원의 관리자는BLAKE이다
WARD사원의 관리자는BLAKE이다
ALLEN사원의 관리자는BLAKE이다
MILLER사원의 관리자는CLARK이다
CLARK사원의 관리자는KING이다
BLAKE사원의 관리자는KING이다
JONES사원의 관리자는KING이다
SMITH사원의 관리자는FORD이다

관리자 정보
--------------------------------------------------------------------------------
KING사원의 관리자는이다 # LEFT(MGR) 의 모든것이 나옴


<ANSI>


SELECT W.ENAME || '사원의 관리자는' || M.ENAME || '이다' AS "관리자 정보"
FROM EMP W LEFT OUTER JOIN EMP M ON (W.MGR = M.EMPNO); (칼럼이름이 다르면 ON)

 

SQL> SELECT W.ENAME || '사원의 관리자는' || M.ENAME || '이다' AS "관리자 정보"
  2  FROM EMP W LEFT OUTER JOIN EMP M ON (W.MGR = M.EMPNO);

# JOIN ~ ON (조인 조건식)

관리자 정보
--------------------------------------------------------------------------------
FORD사원의 관리자는JONES이다
JAMES사원의 관리자는BLAKE이다
TURNER사원의 관리자는BLAKE이다
MARTIN사원의 관리자는BLAKE이다
WARD사원의 관리자는BLAKE이다
ALLEN사원의 관리자는BLAKE이다
MILLER사원의 관리자는CLARK이다
CLARK사원의 관리자는KING이다
BLAKE사원의 관리자는KING이다
JONES사원의 관리자는KING이다
SMITH사원의 관리자는FORD이다

관리자 정보
--------------------------------------------------------------------------------
KING사원의 관리자는이다

12 rows selected.


Q20)

 

□ NATURAL

  : 조인 대상이 되는 두 테이블에 이름과 자료형 같은 열 찾은 후 그 열을 기준으로 등가조인 함

 

 # 사원이름, 부서번호, 부서명을 조회하자.

 

<오류>
 SELECT ENAME, DEPTNO, DNAME
 FROM EMP NATURAL JOIN DEPT USING(DEPTNO); 

 

# ↑ NATURAL 은 칼럼명을 명시하지 않음

 

<실행>
 SELECT E.ENAME, DEPTNO, D.DNAME
 FROM EMP E NATURAL JOIN DEPT D;

 

SQL>  SELECT ENAME, DEPTNO, DNAME
  2   FROM EMP NATURAL JOIN DEPT USING(DEPTNO);
 FROM EMP NATURAL JOIN DEPT USING(DEPTNO)
                            *
ERROR at line 2:
ORA-00933: SQL command not properly ended

# ==============================================

SQL> SELECT E.ENAME, DEPTNO, D.DNAME
  2  FROM EMP E NATURAL JOIN DEPT D;

ENAME      DEPTNO DNAME
---------- ------ -----------
KING           10 ACCOUNTING
CLARK          10 ACCOUNTING
MILLER         10 ACCOUNTING
FORD           20 RESEARCH
SMITH          20 RESEARCH
JONES          20 RESEARCH
JAMES          30 SALES
TURNER         30 SALES
MARTIN         30 SALES
WARD           30 SALES
ALLEN          30 SALES

ENAME      DEPTNO DNAME
---------- ------ -----------
BLAKE          30 SALES

12 rows selected.

 

Q21)

 

  □ CROSS JOIN : 아무런 조건없이 집합테이블을 연결 , 카테시안곱


SELECT E.ENAME, D.DNAME
FROM EMP E CROSS JOIN DEPT D;

 

SQL> SELECT E.ENAME, D.DNAME
  2  FROM EMP E CROSS JOIN DEPT D;

ENAME      DNAME
---------- -----------
SMITH      ACCOUNTING
ALLEN      ACCOUNTING
WARD       ACCOUNTING
JONES      ACCOUNTING
MARTIN     ACCOUNTING
BLAKE      ACCOUNTING
CLARK      ACCOUNTING
KING       ACCOUNTING
TURNER     ACCOUNTING
JAMES      ACCOUNTING
FORD       ACCOUNTING

ENAME      DNAME
---------- -----------
MILLER     ACCOUNTING
SMITH      RESEARCH
ALLEN      RESEARCH
WARD       RESEARCH
JONES      RESEARCH
MARTIN     RESEARCH
BLAKE      RESEARCH
CLARK      RESEARCH
KING       RESEARCH
TURNER     RESEARCH
JAMES      RESEARCH

ENAME      DNAME
---------- -----------
FORD       RESEARCH
MILLER     RESEARCH
SMITH      SALES
ALLEN      SALES
WARD       SALES
JONES      SALES
MARTIN     SALES
BLAKE      SALES
CLARK      SALES
KING       SALES
TURNER     SALES

ENAME      DNAME
---------- -----------
JAMES      SALES
FORD       SALES
MILLER     SALES
SMITH      OPERATIONS
ALLEN      OPERATIONS
WARD       OPERATIONS
JONES      OPERATIONS
MARTIN     OPERATIONS
BLAKE      OPERATIONS
CLARK      OPERATIONS
KING       OPERATIONS

ENAME      DNAME
---------- -----------
TURNER     OPERATIONS
JAMES      OPERATIONS
FORD       OPERATIONS
MILLER     OPERATIONS

48 rows selected.


Q22)

 

□  NON-EQUI JOIN


 # 사원번호, 이름, 직업, 봉급, 봉급의 등급을 출력하자.

 <ORACLE>


 SELECT EMPNO, ENAME, JOB, SAL, GRADE
 FROM SALGRADE, EMP
 WHERE SAL BETWEEN LOSAL AND HISAL;

 

SQL> SELECT EMPNO, ENAME, JOB, SAL, GRADE
  2  FROM SALGRADE, EMP
  3  WHERE SAL BETWEEN LOSAL AND HISAL;

EMPNO ENAME      JOB           SAL GRADE
----- ---------- ----------- ----- -----
 7369 SMITH      CLERK         800     1
 7900 JAMES      CLERK         950     1
 7521 WARD       SALESMAN     1250     2
 7654 MARTIN     SALESMAN     1250     2
 7934 MILLER     CLERK        1300     2
 7844 TURNER     SALESMAN     1500     3
 7499 ALLEN      SALESMAN     1600     3
 7782 CLARK      MANAGER      2450     4
 7698 BLAKE      MANAGER      2850     4
 7566 JONES      MANAGER      2975     4
 7902 FORD       ANALYST      3000     4

EMPNO ENAME      JOB           SAL GRADE
----- ---------- ----------- ----- -----
 7839 KING       PRESIDENT    5000     5

12 rows selected.


 <ANSI>


 SELECT ENAME, SAL, GRADE
 FROM EMP JOIN SALGRADE ON (SAL BETWEEN LOSAL AND HISAL);

SQL>  SELECT ENAME, SAL, GRADE
  2   FROM EMP JOIN SALGRADE ON (SAL BETWEEN LOSAL AND HISAL);

ENAME        SAL GRADE
---------- ----- -----
SMITH        800     1
JAMES        950     1
WARD        1250     2
MARTIN      1250     2
MILLER      1300     2
TURNER      1500     3
ALLEN       1600     3
CLARK       2450     4
BLAKE       2850     4
JONES       2975     4
FORD        3000     4

ENAME        SAL GRADE
---------- ----- -----
KING        5000     5

12 rows selected.

'|Playdata_study > SQL.Oracle' 카테고리의 다른 글

210526_DB4 (SQL) / INSERT, UPDATE, DELETE, MARGE  (0) 2021.05.26
210525 _DB3 (SQL) / 집합(SET)연산, 서브쿼리  (0) 2021.05.25
210521 _DB3 (SQL)  (0) 2021.05.22
210518_DB2 (SQL)  (0) 2021.05.19
210517_ DB 1 (SQL)  (0) 2021.05.17

댓글