S-JIS[2007-07-14/2008-01-27] 変更履歴

rownum擬似列

Oracleの擬似列rownumは、selectした結果(ソート前)の各行に連番を付与してくれるもの。
似たものにrow_number関数がある。これはソート後に連番を付与してくれる。


rownum使用例

SQL> select rownum,empno,ename from emp;

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         1       7369 SMITH
         2       7499 ALLEN
         3       7521 WARD
         4       7566 JONES
         5       7654 MARTIN
         6       7698 BLAKE
         7       7782 CLARK
         8       7788 SCOTT
         9       7839 KING
        10       7844 TURNER
        11       7876 ADAMS
        12       7900 JAMES
        13       7902 FORD
        14       7934 MILLER
        
14行が選択されました。


selectselect
SQL> select rownum,empno,ename from emp
  2  where ename like'%A%';

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         1       7499 ALLEN
         2       7521 WARD
         3       7654 MARTIN
         4       7698 BLAKE
         5       7782 CLARK
         6       7876 ADAMS
         7       7900 JAMES

7行が選択されました。


rownum
SQL> select rownum,empno,ename from emp
  2  where ename like'%A%'
  3  order by ename;

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         6       7876 ADAMS
         1       7499 ALLEN
         4       7698 BLAKE
         5       7782 CLARK
         7       7900 JAMES
         3       7654 MARTIN
         2       7521 WARD

7行が選択されました。

selectrownum使row_number使

Topn


rownumwhere使selectn
SQL> select rownum,empno,ename from emp
  2  where rownum <= 10;

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         1       7369 SMITH
         2       7499 ALLEN
         3       7521 WARD
         4       7566 JONES
         5       7654 MARTIN
         6       7698 BLAKE
         7       7782 CLARK
         8       7788 SCOTT
         9       7839 KING
        10       7844 TURNER

10行が選択されました。

whererownum使

使

1where rownum <= 1where rownum <2
Oracle11SQL





SQL> create function put_number(dt in number) return number
  2 is
  3 begin
  4   dbms_output.put_line(dt);
  5   return dt;
  6 end;
  7 /

ファンクションが作成されました。

SQL> set serveroutputon
SQL> select rownum,empno,ename from emp
  2  where rownum <= 10 and put_number(rownum) >= 0;  ←条件の書き順(andの前後)を入れ替えてみても、結果は同じだった

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         1       7369 SMITH
         2       7499 ALLEN
         3       7521 WARD
         4       7566 JONES
         5       7654 MARTIN
         6       7698 BLAKE
         7       7782 CLARK
         8       7788 SCOTT
         9       7839 KING
        10       7844 TURNER

10行が選択されました。

SQL> exec dbms_output.new_line();
1
2
3
4
5
6
7
8
9
10 ←ちゃんと、put_numberが10回しか呼ばれていない

PL/SQLプロシージャが正常に完了しました。

whererownum使
SQL> select rownum,empno,ename from emp
  2  where put_number(rownum) <= 10;

    ROWNUM      EMPNO ENAME
---------- ---------- ----------
         1       7369 SMITH
         2       7499 ALLEN
         3       7521 WARD
         4       7566 JONES
         5       7654 MARTIN
         6       7698 BLAKE
         7       7782 CLARK
         8       7788 SCOTT
         9       7839 KING
        10       7844 TURNER

10行が選択されました。

SQL> exec dbms_output.new_line();
1
2
3
4
5
6
7
8
9
10
11
11
11
11 ←put_numberが14回(テーブルの全データに対して)呼ばれている

PL/SQLプロシージャが正常に完了しました。

where使

rownum11where10
whererownum

m使
where rownum >= 51rownum1rownum2rownum1510rownum1

row_number


rownumrow_number
overselectorder by
row_number()overORA-30484: 
SQL> select row_number() over(order by ENAME) rn, rownum,EMPNO,ENAME from EMP
  2  where ename like'%A%';

        RN     ROWNUM      EMPNO ENAME
---------- ---------- ---------- ----------
         1          6       7876 ADAMS
         2          1       7499 ALLEN
         3          4       7698 BLAKE
         4          5       7782 CLARK
         5          7       7900 JAMES
         6          3       7654 MARTIN
         7          2       7521 WARD

7行が選択されました。

Top n


row_number使n[2008-01-19]
--DEPTNO毎にSALの上位3件を表示するSQL
select * from
(
 select DEPTNO,ENAME,SAL,
  row_number() over(partition by DEPTNO order by SAL desc) rn
 from EMP
)
where rn <= 3
order by DEPTNO,rn
;
    DEPTNO ENAME             SAL         RN
---------- ---------- ---------- ----------
        10 KING             5020          1
        10 CLARK            2470          2
        10 MILLER           1320          3
        20 SCOTT            3020          1
        20 FORD             3020          2
        20 JONES            2995          3
        30 BLAKE            2870          1
        30 ALLEN            1620          2
        30 TURNER           1520          3

9行が選択されました。

DEPTNO20SCOTTFORDSALSCOTT
partition byorder by
 row_number() over(partition by 項目,項目,… order by 項目 ASC,項目 DESC,…)

KING()


row_number()where11
max()使1
select * from
(
  select
    KEY,
    DATA1, DATA2, …,
    TARGET,
    row_number() over(partition by KEY order by TARGET desc) rn
  from TABLE
)
where rn = 1
;

max()使1

 


ROWNUM使[2008-01-27]
insert into テーブル
select
 ROWNUM, --連番となるキーとか
 '値',
 NULL,
 〜
from all_objects
where ROWNUM <= 50 --50件作成
;

SELECT-INSERT使SELECT
all_objects2
from all_objects,  all_objects
SELECTall_objects22×24()


ROWNUM
使 SQL*Plusvariable,:define,&
SQL> def end=200  ←この番号まで作成する
SQL> var last number ←前回の最大値の保持用
SQL> --現在の最大値を取得
SQL> exec select max(KEY) into :last from TEST_MANY

PL/SQLプロシージャが正常に完了しました。

SQL> print last

      LAST
----------
        50

select  into :PL/SQL使executeSQL
executeSQL-
 
SQL> --データ作成
SQL> insert into TEST_MANY
  2  (KEY) --selectにより設定する項目を列挙
  3  select
  4    ROWNUM + :last
  5  from all_objects
  6  where
  7    ROWMUM + :last <= &end
  8  ;
旧   7:  ROWMUM + :last <= &end
新   7:  ROWMUM + :last <= 200

150行が作成されました。

SQL> select * from TEST_MANY;

       KEY DATA
---------- ----------
         1
         2
         3
〜
       199
       200

200行が選択されました。

ROWNUM1last50ROWNUM + :last51

Oracle / SQL / Oracle /