メモ的な何か

技術的な私のメモになる予定です。

Oracle ROWNUMの使い方

あんまりブログ更新できず、アクセス数もゼロ行進・・・
今回は大きいものじゃないですが、この前仕事でOracle SQL のROWNUMの使い方って特殊って思ったのでまとめてこうと思います。

私の環境はOracle Database Express Edition 11g Release 2VMWare Player上のCentOS7で動かしてる感じで、それをWin上のOracle SQL Developerからアクセスできるようにしました。
ぶっちゃけいうとの環境構築に手間取った感ある・・・

テストテーブルはこんな感じ
数値と名前が入っているシンプルなテーブルです。
f:id:rui_phone:20141012111024p:plain

今回はこのテーブルを数値の小さい順に並べた時の3~5番目を取得するようにしてみたいと思います。
OracleのROWNUMは単純にテーブルの表示順からの位置数を持っていると思っていましたので、以下のように書いて実行しました。
f:id:rui_phone:20141012113359p:plain

実行結果を見た通り、この状態では何も取得されません。
なぜ表示されないかというとROWNUMには1件目(ROWNUM=1)が取得結果に含まれないと正しく表示できないという問題があります。
なので1~5番目とすれば取得は可能です。
f:id:rui_phone:20141012134836p:plain

しかし順番がORDER BYしているにも関わらず、順番がソートされていません。
これは先にROWNUMが処理されてからORDER BYが処理されているため発生します。
この二つの問題を解決するには以下の方法をとらなければなりません。
二段階に分けて進めていきます。
まず以下のSQLを見てください。
f:id:rui_phone:20141012140345p:plain

先にテストテーブルをソートし、それを副問合せとし、そのテーブルに対してROWNUMのカラムを追加しています。
ソートしたものに対してきちんとROWNUMが振れていることがわかると思います。
しかしこのままですと1件目を含めないと取得結果が表示できません。
そこで次のSQLで解決します。
f:id:rui_phone:20141012141437p:plain

先ほどのSQLを副問合せとし、ROWNUMのカラムに対して3~5番目を表示する条件を与えます。
これによって、当初求めたかった「数値の小さい順に並べた時の3~5番目を取得」を達成できました!

大したことを行うような条件ではないのに副問合せを二重で行わなければならないというのが、なんいうか意外でした。