어떻게 분석 함수 로 EMP 표 에서 각 부서 의 임금 이 가장 높 은 직원 을 찾 습 니까?

37329 단어 분석 함수
EMP 표 는 Oracle 테스트 계 정 SCOTT 의 직원 표 입 니 다. 우선 emp 표 의 데 이 터 를 살 펴 보 겠 습 니 다.
SQL> select * from emp;

EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
----- ---------- --------- ---------- --------- ---------- ---------- ----------
 7369 SMITH      CLERK           7902 17-DEC-80        800                    20
 7499 ALLEN      SALESMAN        7698 20-FEB-81       1600       300          30
 7521 WARD       SALESMAN        7698 22-FEB-81       1250       500          30
 7566 JONES      MANAGER         7839 02-APR-81       2975                    20
 7654 MARTIN     SALESMAN        7698 28-SEP-81       1250      1400          30
 7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
 7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
 7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
 7839 KING       PRESIDENT            17-NOV-81       5000                    10
 7844 TURNER     SALESMAN        7698 08-SEP-81       1500         0          30
 7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
 7900 JAMES      CLERK           7698 03-DEC-81        950                    30
 7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
 7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.

그 중에서 empno 는 직원 번호 이자 이 표 의 메 인 키 입 니 다. ename 는 직원 이름 이 고 sal 은 직원 월급 이 며 deptno 는 직원 부서 입 니 다.
어떻게 각 부서 의 최고 임금 직원 정 보 를 찾 습 니까?
자주 사용 하 는 방법 은 관련 조회 입 니 다. SQL 문 구 는 다음 과 같 습 니 다.
select emp.deptno,ename,sal
from emp,
(select deptno,max(sal)maxsal from emp group by deptno) t
where emp.deptno=t.deptno and emp.sal=t.maxsal;

결 과 는 다음 과 같다.
    DEPTNO ENAME             SAL
---------- ---------- ----------
        30 BLAKE            2850
        20 SCOTT            3000
        10 KING             5000
        20 FORD             3000

다음은 실행 계획 을 살 펴 보 자.
Execution Plan
----------------------------------------------------------
Plan hash value: 269884559

-----------------------------------------------------------------------------
| Id  | Operation            | Name   | Rows   | Bytes  | Cost (%CPU) | Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        |      3 |    117 |      7  (15)| 00:00:01 |
|*  1 |  HASH JOIN           |        |      3 |    117 |      7  (15)| 00:00:01 |
|   2 |   VIEW               |        |      3 |     78 |      4  (25)| 00:00:01 |
|   3 |    HASH GROUP BY     |        |      3 |     21 |      4  (25)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| EMP    |     14 |     98 |      3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS FULL  | EMP    |     14 |    182 |      3   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("EMP"."DEPTNO"="T"."DEPTNO" AND "EMP"."SAL"="T"."MAXSAL")


Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
     13  consistent gets
      0  physical reads
      0  redo size
    625  bytes sent via SQL*Net to client
    419  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      4  rows processed

이 조 회 는 같은 시 계 를 대상 으로 두 번 전체 스 캔 을 했 고 원 가 는 7 이 며 논 리 는 13 으로 읽 었 다 는 것 을 알 수 있다.
어떻게 상술 한 조 회 를 최적화 합 니까?여기 서 분석 함수 LAST 를 사용 합 니 다.VALUE,LAST_VALUE 는 정렬 집합의 마지막 값 을 되 돌려 줍 니 다.
SELECT deptno,ename,sal,
       LAST_VALUE(sal)
       OVER(PARTITION BY deptno
            ORDER BY sal
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)maxsal
FROM emp;

출력 결 과 는 다음 과 같 습 니 다.
    DEPTNO ENAME             SAL     MAXSAL
---------- ---------- ---------- ----------
        10 MILLER           1300       5000
        10 CLARK            2450       5000
        10 KING             5000       5000
        20 SMITH             800       3000
        20 ADAMS            1100       3000
        20 JONES            2975       3000
        20 SCOTT            3000       3000
        20 FORD             3000       3000
        30 JAMES             950       2850
        30 MARTIN           1250       2850
        30 WARD             1250       2850
        30 TURNER           1500       2850
        30 ALLEN            1600       2850
        30 BLAKE            2850       2850

14 rows selected.

sal 은 maxsal 과 같은 줄 이 각 부서 의 최고 임금 직원 임 을 알 수 있 습 니 다. 다음은 포 함 된 부분 으로 목표 결 과 를 조회 합 니 다.
SELECT deptno,ename,sal FROM (
       SELECT deptno,ename,sal,
              LAST_VALUE(sal)
              OVER(PARTITION BY deptno
                   ORDER BY sal
                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)maxsal
       FROM emp) WHERE sal=maxsal;

출력 결 과 는 다음 과 같 습 니 다.
    DEPTNO ENAME             SAL
---------- ---------- ----------
        10 KING             5000
        20 SCOTT            3000
        20 FORD             3000
        30 BLAKE            2850

다음은 이 문장의 집행 계획 을 살 펴 보 자.
Execution Plan
----------------------------------------------------------
Plan hash value: 4130734685

----------------------------------------------------------------------------
| Id  | Operation            | Name  | Rows  | Bytes | Cost (%CPU)| Time       |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |       |    14 |   644 |     4  (25)| 00:00:01 |
|*  1 |  VIEW                |       |    14 |   644 |     4  (25)| 00:00:01 |
|   2 |   WINDOW SORT        |       |    14 |   182 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL |  EMP  |    14 |   182 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("SAL"="MAXSAL")


Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
      6  consistent gets
      0  physical reads
      0  redo size
    619  bytes sent via SQL*Net to client
    419  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      1  sorts (memory)
      0  sorts (disk)
      4  rows processed

이 를 통 해 알 수 있 듯 이 분석 함 수 를 도입 한 후에 원가 와 논리 적 읽 기 가 모두 절반 으로 줄 었 다.
조회 결 과 를 통 해 우 리 는 20 호 부서 에서 두 사람의 월급 이 가장 높 은 것 을 알 수 있 습 니 다. 가끔 우 리 는 한 사람의 정 보 를 얻 고 싶 습 니 다. 어떻게 실현 합 니까?
여기 서 우 리 는 분석 함수 LAG 를 사용 할 것 입 니 다. 구체 적 인 SQL 은 다음 과 같 습 니 다.
SELECT deptno,ename,sal,LAG(sal)OVER(ORDER BY deptno) presal FROM (
       SELECT deptno,ename,sal,
              LAST_VALUE(sal)
              OVER(PARTITION BY deptno
              ORDER BY sal
              ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)maxsal
       FROM emp) WHERE sal=maxsal;

출력 결 과 는 다음 과 같 습 니 다.
    DEPTNO ENAME             SAL     PRESAL
---------- ---------- ---------- ----------
        10 KING             5000
        20 SCOTT            3000       5000
        20 FORD             3000       3000
        30 BLAKE            2850       3000

sal 을 제거 하 는 것 은 presal 과 같은 줄 입 니 다.
SELECT deptno,ename,sal FROM (
       SELECT deptno,ename,sal,LAG(sal)OVER(ORDER BY deptno) presal FROM (
              SELECT deptno,ename,sal,
                     LAST_VALUE(sal)
                     OVER(PARTITION BY deptno
                     ORDER BY sal
                     ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)maxsal
               FROM emp) 
       WHERE sal=maxsal) WHERE sal <> presal or presal is null;

출력 결 과 는 다음 과 같 습 니 다.
    DEPTNO ENAME             SAL
---------- ---------- ----------
        10 KING             5000
        20 SCOTT            3000
        30 BLAKE            2850

요약:
실제 생산 환경 에서 이런 응용 은 매우 많다. 예 를 들 어 모든 시간 대 에 가장 많은 시간 을 소모 하 는 작업 명세 서 를 어떻게 조회 하 는 지 등 이다.물론 상기 시연 을 통 해 우 리 는 group by 함수 의 한계점 을 알 수 있다.
LAST 에 대하 여VALUE 와 LAG 함수 의 구체 적 인 응용 및 설명 은 Oracle 공식 문 서 를 참고 할 수 있 습 니 다.
1.  LAST_VALUE
2. LAG

좋은 웹페이지 즐겨찾기