【Oracle SQL*Plus】ROWNUM指定による行取得で期待されるレコードが取得出来ない。【トラブルシューティング】
備忘録になります。ROWNUM指定による行取得で期待されるレコードが取得出来ないケースについてまとめました。
ケース①:違うレコードが取得された
SQL> SELECT * FROM TEST_TABLE
2 ORDER BY ID;
1,NAME-A , 1,A
2,NAME-B , 2,B
3,NAME-C , 3,C
4,NAME-D , 4,D
5,NAME-E , 5,E
SQL> SELECT * FROM TEST_TABLE
2 WHERE ROWNUM <= 3
3 ORDER BY ID;
2,NAME-B , 2,B
3,NAME-C , 3,C
4,NAME-D , 4,D
IDが1~3のレコードを表示させたいが、ソートが効かず、2~4が表示されている。WHERE句に利用する場合、ORDER BYやGROUP BYより優先順位が高いため、ソート後やグループ化後の結果に対しての行番号を使いたい場合は工夫が必要です。解決法として、私はサブクエリを使って回避しています。
SQL> SELECT * FROM (
2 SELECT * FROM TEST_TABLE
3 ORDER BY ID)
4 WHERE ROWNUM <= 3;
1,NAME-A , 1,A
2,NAME-B , 2,B
3,NAME-C , 3,C
ケース②:レコードが取得できない
SQL> SELECT * FROM TEST_TABLE;
2,NAME-B , 2,B
3,NAME-C , 3,C
4,NAME-D , 4,D
5,NAME-E , 5,E
1,NAME-A , 1,A
SQL> SELECT * FROM TEST_TABLE
2 WHERE ROWNUM = 3
レコードが選択されませんでした。
「ROWNUM = 3」のような指定は期待通り表示されません。ROWNUM = 1からチェックされ、条件を満たされない時点で表示終了する仕様のようです。解決策としてはソート済な項目に対し、ORDER BYを使って表示を逆転させてから先頭行を取る工夫をします。
SQL> SELECT * FROM (
2 SELECT * FROM TEST_TABLE
3 WHERE ROWNUM <= 3
4 ORDER BY ID DESC)
5 WHERE ROWNUM = 1;
4,NAME-D , 4,D
関連記事