Oracle ROWNUM とページネーション: 一般的な問題と解決策
この記事では、Oracle SQL でのページネーションに ROWNUM
を使用するときに発生する頻繁な問題について説明します。
問題 1: WHERE
ROWNUM
を含む無効な
SELECT * FROM Person WHERE rownum > 100
が結果を返さないのはなぜですか?
ROWNUM
は、最初のフィルタリング (述語) フェーズの後 に割り当てられます。 ROWNUM
値は代入後にのみ増加するため、この方法で WHERE
句を使用して 1 より大きい値を直接選択することはできません。 条件 ROWNUM > 100
を満たす行はありません。
問題 2: ROWNUM BETWEEN
制限事項
WHERE rownum BETWEEN lowerBound AND upperBound
がページネーションに適していないのはなぜですか?
ROWNUM
代入が WHERE
句の評価に先行するため、この構文も無効です。 Oracle は ROWNUM
値の範囲を直接選択できません。
解決策: Oracle 12c 以降 (上位行制限)
Oracle 12c では、OFFSET
と FETCH
を使用した「トップ n 行制限」という優れたアプローチが導入されました。 例:
<code class="language-sql">SELECT empno, sal FROM emp ORDER BY sal OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;</code>
これにより、行 5 ~ 8 が効率的に取得されます (オフセット 4、フェッチ 4)。 この方法は、ROWNUM
のみに依存する手法よりも優先されます。
問題 3: ROWNUM
列を非表示にする
ROWNUM
列が結果セットに表示されないようにするにはどうすればよいですか?
外側の SELECT
ステートメントに必要な列のみをリストするだけです。 あるいは、SQL*Plus では、NOPRINT
コマンドを使用して特定の列の出力を抑制できます。
問題 4: ROWNUM
(古い Oracle バージョン) で正しいページネーションを確保する
ROWNUM
は正しいページネーションを実現できますか?
はい、ただし、ネストされたクエリ構造が必要です:
<code class="language-sql">SELECT val FROM (SELECT val, rownum AS rnum FROM (SELECT val FROM t ORDER BY val) WHERE rownum <= 8) WHERE rnum >= 5;</code>
これにより、行 5 ~ 8 が正しく取得されます。 内側のクエリは ROWNUM
を割り当て、中央のクエリは上限に基づいてフィルタし、外側のクエリは下限に基づいてフィルタします。 ただし、Oracle 12c 以降でも、OFFSET
/FETCH
メソッドがより効率的で読みやすいオプションであり続けます。
以上がOracle の ROWNUM: 適切なページネーションを実現し、よくある落とし穴を回避するには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。