본문 바로가기

Oracle/ROWNUM

Oracle ROWNUM 에 대하여

Oracle Paging 방법에 대한 테스트 (ROWNUM의 이해)

Oracle Paging 방법에 대한 테스트 내용

Oracle Paging방법은 ROWNUM이란 임시컬럼을 사용하므로 ROWNUM에 대해 알아 볼 필요가 있다.

ROWNUM: 결과집합에 대한 가상의 순번

**결과집합이 메모리에 생성된 경우에 결과집합 내의 각 레코드에 붙여지는 가상의 순번
참고로, ORDER BY 정렬은 결과집합이 생성된 후에 적용되는 정렬조건이므로 OREDR BY ROWNUM DESC와 같은 표현이 가능하다.

Oracle시스템이 제공하는 ROWNUM은 임시 컬럼으로,  레코드를 선택한 직후에 오라클이  각 레코드에 순차적으로 일련의 번호를 붙인 것이다. 오라클시스템은 선택된 레코드에 순서대로 번호를 붙이고 이 번호를 ROWNUM이란 임시컬럼으로 제공하고 있다. 주의할 점은 order by는 선택된 레코드를 정렬하는 것이므로 선택한 후에 실행되는 정렬 조건이므로 선택당시에 적용되는 ROWNUM보다 나중에 적용된다는 것을 의미한다. 그러므로  order by에는 ROWNUM을 적용할 수도 있다. 반면에, where 조건은 레코드가 선택되기 전에 참조되므로 where 조건에 ROWNUM을 사용하면 결과값이 없을 수도 있다.

다중쿼리를 사용할 때, 앞 쿼리가 실행되어 설정된 ROWNUM 을 다음 쿼리에서도 사용하려면 select ROWNUM, ...... 처럼 분명히 선택해 주어야 한다. 다중쿼리를 실행할 때, 앞의 쿼리에서 생성된 ROWNUM을 사용할 생각이라면 다음과 같이 작성해야 한다.
select * from (select ROWNUM, e.* from emp e);

결과는 다음과 같다.

SQL> select * from (select ROWNUM, e.* from emp e);

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
         1       7369 SMITH      CLERK           7902 80/12/17        800                    20
         2       7499 ALLEN      SALESMAN        7698 81/02/20       1600        300         30
         3       7521 WARD       SALESMAN        7698 81/02/22       1250        500         30
         4       7566 JONES      MANAGER         7839 81/04/02       2975                    20
         5       7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400         30
         6       7698 BLAKE      MANAGER         7839 81/05/01       2850                    30
         7       7782 CLARK      MANAGER         7839 81/06/09       2450                    10
         8       7788 SCOTT      ANALYST         7566 87/04/19       3000                    20
         9       7839 KING       PRESIDENT            81/11/17       5000                    10
        10       7844 TURNER     SALESMAN        7698 81/09/08       1500          0         30
        11       7876 ADAMS      CLERK           7788 87/05/23       1100                    20

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
        12       7900 JAMES      CLERK           7698 81/12/03        950                    30
        13       7902 FORD       ANALYST         7566 81/12/03       3000                    20
        14       7934 MILLER     CLERK           7782 82/01/23       1300                    10

14 개의 행이 선택되었습니다.

위의 SQL 문장을 살펴보면, 안쪽 문장이 먼저 실행될 때 발생한 ROWNUM을 명시적으로 select의 대상에 포함시켰기 때문에 결과 집합에서는 한개의 컬럼으로 자리를 잡고 있으므로 다음 쿼리가 실행될 때 앞서 생성된 ROWNUM에 접근할 수가 있다.

다음 쿼리 2개를 비교해 보면 2중쿼리에서 각각의 쿼리가 ROWNUM 을 결과집합에 포함시킬 경우 안쪽에서 생성된 ROWNUM은 참조되지 않고 바깥에서 새로 생성된 ROWNUM이 참조되는 것을 알 수 있다.

SQL> select * from (select ROWNUM, ename from emp order by sal desc);

    ROWNUM ENAME
---------- ----------
         9 KING
         8 SCOTT
        13 FORD
         4 JONES
         6 BLAKE
         7 CLARK
         2 ALLEN
        10 TURNER
        14 MILLER
         3 WARD
         5 MARTIN

    ROWNUM ENAME
---------- ----------
        11 ADAMS
        12 JAMES
         1 SMITH

14 개의 행이 선택되었습니다.

SQL> select ROWNUM, ename from (select ROWNUM, ename from emp order by sal desc);

    ROWNUM ENAME
---------- ----------
         1 KING
         2 SCOTT
         3 FORD
         4 JONES
         5 BLAKE
         6 CLARK
         7 ALLEN
         8 TURNER
         9 MILLER
        10 WARD
        11 MARTIN

    ROWNUM ENAME
---------- ----------
        12 ADAMS
        13 JAMES
        14 SMITH

14 개의 행이 선택되었습니다.

다중쿼리를 사용할 때 앞의 쿼리에서 발생한 ROWNUM을 다음 쿼리에서 사용할 생각이라면 다음과 같이 작성해야 한다.

SQL> select RN, ename from (select ROWNUM RN, e.* from emp e order by sal desc);

        RN ENAME
---------- ----------
         9 KING
         8 SCOTT
        13 FORD
         4 JONES
         6 BLAKE
         7 CLARK
         2 ALLEN
        10 TURNER
        14 MILLER
         3 WARD
         5 MARTIN

        RN ENAME
---------- ----------
        11 ADAMS
        12 JAMES
         1 SMITH

14 개의 행이 선택되었습니다.



그러므로 다음과 같이 정리할 수 있겠다.
ROWNUM 이라는 컬럼은 단위 SQL문장이 실행될 때 자동으로 생성되어 ORDER BY 같은 곳에서 사용할 수 있지만, 해당 단위 문장이 실행된 후, 바깥쿼리에서는 안쪽 쿼리실행 중 생성된 ROWNUM을 참조할 수 없게 된다. 만약, 앞의 쿼리에서 발생한 ROWNUM 을 다음 쿼리에서도 사용하려면 앞의 쿼리가 실행될 때 분명히 결과집합에 포함시켜 주어야 한다. 즉, select * from (select ROWNUM, e.* from emp e order by ROWNUM desc); 과 같이 해 주어야 한다. 만약 바깥 쿼리에서도 select ROWNUM 처럼 하면 바깥쿼리를 실행할 때 또 다시 ROWNUM이 생성되므로 안쪽에서 생성된 ROWNUM과는 상관이 없는 다른 컬럼이 된다.

다음과 같은 문장을 테스트해 본다.

select ROWNUM, t.* from (select ROWNUM rn, e.* from emp e order by ROWNUM desc)t;

SQL> select ROWNUM, t.* from (select ROWNUM rn, e.* from emp e order by ROWNUM desc)t;

    ROWNUM RN      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM 
---------- ---------- ---------- ---------- --------- ---------- -------- ---------- ---------- -
         1         14       7934 MILLER     CLERK           7782 82/01/23       1300                   
         2         13       7902 FORD       ANALYST         7566 81/12/03       3000                   
         3         12       7900 JAMES      CLERK           7698 81/12/03        950                   
         4         11       7876 ADAMS      CLERK           7788 87/05/23       1100                   
         5         10       7844 TURNER     SALESMAN        7698 81/09/08       1500          0        
         6          9       7839 KING       PRESIDENT            81/11/17       5000                   
         7          8       7788 SCOTT      ANALYST         7566 87/04/19       3000                   
         8          7       7782 CLARK      MANAGER         7839 81/06/09       2450                   
         9          6       7698 BLAKE      MANAGER         7839 81/05/01       2850                   
        10          5       7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400        
        11          4       7566 JONES      MANAGER         7839 81/04/02       2975                   

    ROWNUM         RN      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM 
---------- ---------- ---------- ---------- --------- ---------- -------- ---------- ---------- -
        12          3       7521 WARD       SALESMAN        7698 81/02/22       1250        500        
        13          2       7499 ALLEN      SALESMAN        7698 81/02/20       1600        300        
        14          1       7369 SMITH      CLERK           7902 80/12/17        800                   

14 개의 행이 선택되었습니다.

앞선 쿼리에서 RN 이란 이름으로 ROWNUM을 결과집합에 포함시켰기 때문에 다음 쿼리에서 사용이 가능해 졌고, 또 다음 쿼리에서 발생한 ROWNUM 도 앞의 쿼리와 분리되어 독자적으로 생성되는 것을 확인할 수 있다.

SQL> select ROWNUM, ename, sal from (select ROWNUM, ename, sal from emp order by sal asc) where ROWNUM between 5 and 10;

선택된 레코드가 없습니다.

위의 문장을 살펴보면 where 절에서 ROWNUM을 사용하고 있지만 결과가 없다고 나온다. 안쪽에서 생성된 ROWNUM 이 바깥에서도 그대로 사용되기를 바라면서 작성한 문장이지만 바깥 쿼리에서 언급한 ROWNUM은 안쪽에서 생성된 ROWNUM과 무관하다. 그러므로 안쪽에서 생성된 ROWNUM을 바깥쿼리에서도 참조하려면 안쪽 쿼리의 select 문장에서 ROWNUM을 사용하면서 별칭을 하나 붙여주고 그 별칭을 바깥쿼리에서 참조하면 된다. 위의 문장을 다음과 같이 수정하면 된다.

SQL> select * from (select ROWNUM RN, ename, sal from (select ename, sal from emp order by sal asc))
 where RN between 5 and 10;

        RN ENAME             SAL
---------- ---------- ----------
         5 MARTIN           1250
         6 MILLER           1300
         7 TURNER           1500
         8 ALLEN            1600
         9 CLARK            2450
        10 BLAKE            2850

6 개의 행이 선택되었습니다.

위의 문장에서 맨 안쪽의 쿼리는 SAL 순으로 레코드를 정렬하는 기능을 하고, 중간에 위치한 쿼리는 안쪽의 결과집합에 ROWNUM 컬럼을 추가하는 기능, 맨 바깥쿼리는 안쪽에서 추가한 순번을 이용하여 구간 검색을 하고 있다.

다음과 같은 테스트를 통해서 ROWNUM의 사용법을 알아본다.

SQL> select ROWNUM, ename from emp;

    ROWNUM ENAME
---------- ----------
         1 SMITH
         2 ALLEN
         3 WARD
         4 JONES
         5 MARTIN
         6 BLAKE
         7 CLARK
         8 SCOTT
         9 KING
        10 TURNER
        11 ADAMS
        12 JAMES
        13 FORD
        14 MILLER

14 개의 행이 선택되었습니다.

SQL> select ROWNUM, ename from emp where ROWNUM between 4 and 6;

선택된 레코드가 없습니다.

해설: 위의 결과에서 나타나듯이 ROWNUM은 오라클이 결과집합을 메모리에 생성한 후에 설정하기 때문에 WHERE 절에서 아직 없는 컬럼을 먼저 참조하려는 격이기 때문에 선택된 결과가 없다고 나온다.

SQL> select * from (select rownum rn, ename from emp) where rownum between 1 and 5;

        RN ENAME
---------- ----------
         1 SMITH
         2 ALLEN
         3 WARD
         4 JONES
         5 MARTIN

SQL> select * from (select rownum rn, ename from emp) where rownum between 6 and 10;
선택된 레코드가 없습니다.

SQL> select ROWNUM, ename from emp order by ROWNUM desc;

    ROWNUM ENAME
---------- ----------
        14 MILLER
        13 FORD
        12 JAMES
        11 ADAMS
        10 TURNER
         9 KING
         8 SCOTT
         7 CLARK
         6 BLAKE
         5 MARTIN
         4 JONES
         3 WARD
         2 ALLEN
         1 SMITH

14 개의 행이 선택되었습니다.

SQL> select rownum, e.* from emp e order by rownum desc;

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
        14       7934 MILLER     CLERK           7782 82/01/23       1300                    10
        13       7902 FORD       ANALYST         7566 81/12/03       3000                    20
        12       7900 JAMES      CLERK           7698 81/12/03        950                    30
        11       7876 ADAMS      CLERK           7788 87/05/23       1100                    20
        10       7844 TURNER     SALESMAN        7698 81/09/08       1500          0         30
         9       7839 KING       PRESIDENT            81/11/17       5000                    10
         8       7788 SCOTT      ANALYST         7566 87/04/19       3000                    20
         7       7782 CLARK      MANAGER         7839 81/06/09       2450                    10
         6       7698 BLAKE      MANAGER         7839 81/05/01       2850                    30
         5       7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400         30
         4       7566 JONES      MANAGER         7839 81/04/02       2975                    20

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
         3       7521 WARD       SALESMAN        7698 81/02/22       1250        500         30
         2       7499 ALLEN      SALESMAN        7698 81/02/20       1600        300         30
         1       7369 SMITH      CLERK           7902 80/12/17        800                    20

14 개의 행이 선택되었습니다.

SQL> select rownum, t.* from (select * from emp order by rownum desc)t;

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
         1       7934 MILLER     CLERK           7782 82/01/23       1300                    10
         2       7902 FORD       ANALYST         7566 81/12/03       3000                    20
         3       7900 JAMES      CLERK           7698 81/12/03        950                    30
         4       7876 ADAMS      CLERK           7788 87/05/23       1100                    20
         5       7844 TURNER     SALESMAN        7698 81/09/08       1500          0         30
         6       7839 KING       PRESIDENT            81/11/17       5000                    10
         7       7788 SCOTT      ANALYST         7566 87/04/19       3000                    20
         8       7782 CLARK      MANAGER         7839 81/06/09       2450                    10
         9       7698 BLAKE      MANAGER         7839 81/05/01       2850                    30
        10       7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400         30
        11       7566 JONES      MANAGER         7839 81/04/02       2975                    20

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ----------
        12       7521 WARD       SALESMAN        7698 81/02/22       1250        500         30
        13       7499 ALLEN      SALESMAN        7698 81/02/20       1600        300         30
        14       7369 SMITH      CLERK           7902 80/12/17        800                    20

14 개의 행이 선택되었습니다.

SQL> select ename from emp order by ROWNUM desc;

ENAME
----------
MILLER
FORD
JAMES
ADAMS
TURNER
KING
SCOTT
CLARK
BLAKE
MARTIN
JONES
WARD
ALLEN
SMITH

14 개의 행이 선택되었습니다.

SQL> select rownum, ename from emp;

    ROWNUM ENAME
---------- ----------
         1 SMITH
         2 ALLEN
         3 WARD
         4 JONES
         5 MARTIN
         6 BLAKE
         7 CLARK
         8 SCOTT
         9 KING
        10 TURNER
        11 ADAMS

    ROWNUM ENAME
---------- ----------
        12 JAMES
        13 FORD
        14 MILLER

14 개의 행이 선택되었습니다.

==> 위의 결과는 아루런 정렬조건없이 레코드를 선택한 후 선택된 레코드에 순차적으로 번호(ROWNUM)를 붙인 것이다.

SQL> select ROWNUM, ENAME from emp order by ename;

    ROWNUM ENAME
---------- ----------
        11 ADAMS
         2 ALLEN
         6 BLAKE
         7 CLARK
        13 FORD
        12 JAMES
         4 JONES
         9 KING
         5 MARTIN
        14 MILLER
         8 SCOTT

    ROWNUM ENAME
---------- ----------
         1 SMITH
        10 TURNER
         3 WARD

14 개의 행이 선택되었습니다.

==>선택할 경우에 정렬조건보다 먼저 ROWNUM이 적용된다는 것을 알 수 있다.
선택된 레코드가 메모리에 결과집합으로 생성될 때 순차적으로 ROWNUM이 적용된다는 것이다. 또 달리 표현하면, 레코드를 선택하여 메모리에 결과 집합이 생성된 후에 order by 정렬 조건을 적용한다는 의미이다.

SQL> select ROWNUM, t.* from (select empno, ename, sal from emp order by ename)t;

    ROWNUM      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
         1       7876 ADAMS            1100
         2       7499 ALLEN            1600
         3       7698 BLAKE            2850
         4       7782 CLARK            2450
         5       7902 FORD             3000
         6       7900 JAMES             950
         7       7566 JONES            2975
         8       7839 KING             5000
         9       7654 MARTIN           1250
        10       7934 MILLER           1300
        11       7788 SCOTT            3000

    ROWNUM      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
        12       7369 SMITH             800
        13       7844 TURNER           1500
        14       7521 WARD             1250

14 개의 행이 선택되었습니다.

==> 위의 결과는, 선택하고 정렬을 한 다음, 그 결과를 다시 선택하면 원하는 정렬에 순차적으로 번호를 부여할 수 있다.

위와 같은 테스트 결과를 참고로 하여, 다음 문제를 해결해 보자.

문제 1) 급여 순위가 1위~5위 사이에 해당하는 사원들의 순위, 사원번호, 이름, 급여를 출력해 보자.

SQL> select ROWNUM 순위, t.* from (select empno, ename, sal from emp order by sal desc)t;

      순위      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
         1       7839 KING             5000
         2       7788 SCOTT            3000
         3       7902 FORD             3000
         4       7566 JONES            2975
         5       7698 BLAKE            2850
         6       7782 CLARK            2450
         7       7499 ALLEN            1600
         8       7844 TURNER           1500
         9       7934 MILLER           1300
        10       7521 WARD             1250
        11       7654 MARTIN           1250

      순위      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
        12       7876 ADAMS            1100
        13       7900 JAMES             950
        14       7369 SMITH             800

14 개의 행이 선택되었습니다.


문제 2) 사원번호 순으로 순번을 포함하여 empno, ename, sal 를 출력해 보자.

SQL> select ROWNUM, t.* from (select empno, ename, sal from emp order by empno) t;

    ROWNUM      EMPNO ENAME             SAL
---------- ---------- ---------- ----------
         1       7369 SMITH             800
         2       7499 ALLEN            1600
         3       7521 WARD             1250
         4       7566 JONES            2975
         5       7654 MARTIN           1250
         6       7698 BLAKE            2850
         7       7782 CLARK            2450
         8       7788 SCOTT            3000
         9       7839 KING             5000
        10       7844 TURNER           1500
        11       7876 ADAMS            1100
        12       7900 JAMES             950
        13       7902 FORD             3000
        14       7934 MILLER           1300

14 개의 행이 선택되었습니다.

문제 3) 급여순위 중에서 1위와 10위의 급여액 차이를 출력해 보자.

SQL> select max(sal)-min(sal) 차액 from (select sal from (select sal from emp order by sal desc) where ROWNUM between 1 and 10);

      차액
----------
      3750

문제 4) 사번(empno)순으로 출력하되, 한페이지 당 3개의 레코드를 출력할 때, 두번째 페이지(4~6번 항목)를 출력하시오.

SQL> select t2.* from (select ROWNUM rn, t.* from (select empno, ename from emp order by empno)t)t2 where t2.rn between 4 and 6;

        RN      EMPNO ENAME
---------- ---------- ----------
         4       7566 JONES
         5       7654 MARTIN
         6       7698 BLAKE

SQL> select rownum, p.* from (select * from emp order by ename)p where rownum between 1 and 5;

    ROWNUM      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO DNAME
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ----
         1       7876 ADAMS      CLERK           7788 87/05/23       1100                    20 RESEARCH
         2       7499 ALLEN      SALESMAN        7698 81/02/20       1600        300         30 SALES
         3       7698 BLAKE      MANAGER         7839 81/05/01       2850                    30 SALES
         4       7782 CLARK      MANAGER         7839 81/06/09       2450                    10 ACCOUNTING
         5       7902 FORD       ANALYST         7566 81/12/03       3000                    20 RESEARCH


 

SQL> select rownum, p.* from (select * from emp order by ename)p where rownum between 6 and 10;

선택된 레코드가 없습니다.


=> where 절이 먼저 실행될 때 rownum을 갖는 레코드는 없는 상태이므로 위와 같은 결과가 출력된다.

SQL> select * from (select rownum rn, p.* from (select * from emp order by ename)p) where rn between 6 and 10;

        RN      EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO DNAME
---------- ---------- ---------- --------- ---------- -------- ---------- ---------- ---------- ----
         6       7900 JAMES      CLERK           7698 81/12/03        950                    30 SALES
         7       7566 JONES      MANAGER         7839 81/04/02       2975                    20 RESEARCH
         8       7839 KING       PRESIDENT            81/11/17       5000                    10 ACCOUNTING
         9       7654 MARTIN     SALESMAN        7698 81/09/28       1250       1400         30 SALES
        10       7934 MILLER     CLERK           7782 82/01/23       1300                    10 ACCOUNTING

=> order by로 정렬된 집합에 다시 쿼리하여 rownum을 추가해 주면 where절에서도 rownum을 사용할 수가 있다.

위의 문장에서 BETWEEN ? AND ? 부분에 시작라인 번호와 끝 라인번호를 대입해 주면 페이징을 구현할 수 있을 것입니다.

SQL문장을 받은 오라클은 데이터를 검색하여 그 결과를 메모리에 로드하고 위에서부터 순서에 따라서 각 레코드에 ROWNUM을 부여한다. 이 때 오라클이 부여한 ROWNUM을 현재의 단위 SQL문장(해당문장내의 ORDER BY 등)에서는 자유롭게 사용할 수가 있지만, 다음에 이어지는 쿼리에서  사용하기 위해서는 select 문장에 ROWNUM을 포함해야만 바깥쿼리에서 안쪽쿼리의 ROWNUM 값에 접근할 수가 있다. select 문장에 ROWNUM을 포함하지 않은 경우에는 오라클이 내부에서 단위 SQL문장이 실행될 때만 그 문장 안에서 그 값(ROWNUM)을 사용할 수 있을 뿐, 다른 쿼리에서는 접근할 수 없게 된다고 생각하면 된다.

연습문제 1)
EMP 테이블에서 SAL 오름차 순으로 정렬하는 문장을 작성해 보세요.

SQL> select * from emp order by sal;

     EMPNO ENAME      JOB              MGR HIREDATE        SAL 
---------- ---------- --------- ---------- -------- ----------
      7369 SMITH      CLERK           7902 80/12/17        800 
      7900 JAMES      CLERK           7698 81/12/03        950 
      7876 ADAMS      CLERK           7788 87/05/23       1100 
      7521 WARD       SALESMAN        7698 81/02/22       1250 
      7654 MARTIN     SALESMAN        7698 81/09/28       1250 
      7934 MILLER     CLERK           7782 82/01/23       1300 
      7844 TURNER     SALESMAN        7698 81/09/08       1500 
      7499 ALLEN      SALESMAN        7698 81/02/20       1600 
      7782 CLARK      MANAGER         7839 81/06/09       2450 
      7698 BLAKE      MANAGER         7839 81/05/01       2850 
      7566 JONES      MANAGER         7839 81/04/02       2975 

     EMPNO ENAME      JOB              MGR HIREDATE        SAL 
---------- ---------- --------- ---------- -------- ----------
      7788 SCOTT      ANALYST         7566 87/04/19       3000 
      7902 FORD       ANALYST         7566 81/12/03       3000 
      7839 KING       PRESIDENT            81/11/17       5000 

14 개의 행이 선택되었습니다.

연습문제 2)
EMP 테이블에서 SAL 오름차 순으로 정렬하여 순번을 표시해 보세요.

SQL> select ROWNUM 순번, e.* from (select * from emp order by sal)e;

      순번      EMPNO ENAME      JOB              MGR HIREDATE        SAL      
---------- ---------- ---------- --------- ---------- -------- ----------
         1       7369 SMITH      CLERK           7902 80/12/17        800      
         2       7900 JAMES      CLERK           7698 81/12/03        950      
         3       7876 ADAMS      CLERK           7788 87/05/23       1100      
         4       7521 WARD       SALESMAN        7698 81/02/22       1250      
         5       7654 MARTIN     SALESMAN        7698 81/09/28       1250      
         6       7934 MILLER     CLERK           7782 82/01/23       1300      
         7       7844 TURNER     SALESMAN        7698 81/09/08       1500      
         8       7499 ALLEN      SALESMAN        7698 81/02/20       1600      
         9       7782 CLARK      MANAGER         7839 81/06/09       2450      
        10       7698 BLAKE      MANAGER         7839 81/05/01       2850      
        11       7566 JONES      MANAGER         7839 81/04/02       2975      

      순번      EMPNO ENAME      JOB              MGR HIREDATE        SAL      
---------- ---------- ---------- --------- ---------- -------- ----------
        12       7788 SCOTT      ANALYST         7566 87/04/19       3000      
        13       7902 FORD       ANALYST         7566 81/12/03       3000      
        14       7839 KING       PRESIDENT            81/11/17       5000      

14 개의 행이 선택되었습니다.

연습문제 3)
EMP 테이블에서 SAL 오름차 순으로 정렬하여 순번을 표시하여 출력하되 순번이 5~10 사이에 해당하는 레코드만 출력해 보세요.

SQL> select 순위, ename, sal from(select ROWNUM 순위, ename, sal from (select * from emp order by sal)) where 순위 between 5 and 10;

      순위 ENAME             SAL
---------- ---------- ----------
         5 MARTIN           1250
         6 MILLER           1300
         7 TURNER           1500
         8 ALLEN            1600
         9 CLARK            2450
        10 BLAKE            2850

6 개의 행이 선택되었습니다.

연습문제 4)
EMP 테이블에서 SAL 오름차 순으로 정렬하여 순번을 표시하여 출력하되, JSP 프로그램을 이용하여 브라우저에서 전달된 파라미터 2개를 이용하여 구간검색 결과를 브라우저 화면에 출력하는 프로그램을 작성해 보세요.

rownum_emp.jsp

<%@ page contentType="text/html;charset=KSC5601"%>
<%@ page import="java.sql.*"%>
<HTML>
<HEAD>
<TITLE>Oracle ROWNUM Test </TITLE>
</HEAD>
<BODY>
<%
 String jdbc_driver = "oracle.jdbc.OracleDriver";
 String db_url = "jdbc:oracle:thin:@localhost:1521:ORA9I";
 Class.forName("oracle.jdbc.OracleDriver");
 Connection conn = DriverManager.getConnection(db_url, "scott", "tiger");
 String sql= "select * from (select ROWNUM RN, ename, sal from (select ename, sal from emp order by sal asc)) where RN between ? and ?";
 PreparedStatement pstmt = conn.prepareStatement(sql);
 pstmt.setInt(1, 5);
 pstmt.setInt(2, 10);
 ResultSet rs = pstmt.executeQuery();
 while(rs.next()){
  for(int i=1;i<=3;i++){
   out.print(rs.getString(i)+" ");
  }
  out.println("<br>");
 }
%>
</BODY>
</HTML>