0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Oracleには、取得するレコード数を制限するLIMIT句がないです。
その代わりにROWNUM疑似列というものが用意されており、LIMITの代用が可能です。

SELECT * FROM table WHERE ROWNUM <= 10;

問題点

ただORDER BYGROUP BYを併用する場合、意図した結果となりません。
ソートやグループ化の前にROWNUMが行われるようです。

解決

ググると、FROM句をサブクエリとして、そこでORDER BYGROUP BYすればいいようです。

SELECT
    *
FROM
    (SELECT * FROM table ORDER BY column)    
WHERE 
    ROWNUM <= 10;

なるほど!
…ではあるんですが、面倒ですね。

さらにOFFSETを行いたい場合、ROW_NUMBER()ウィンドウ関数を使用して、下記のようにする必要があります。
ROW_NUMBER()で行番号を採番し、BETWEENで取得範囲を指定します。

SELECT
  *
FROM
  ( 
    SELECT
      table.*,
      ROW_NUMBER() OVER (ORDER BY column) AS row_number
    FROM
      table
  ) 
WHERE
  row_number BETWEEN 1 AND 10;

さらに面倒ですね…

よりよい方法(条件付き)

Oracle 12c からFETCH FIRST句とOFFSET句が用意され、記述がとても楽になりました。

    SELECT
      *
    FROM
      table
    ORDER BY column
    FETCH FIRST 10 ROWS ONLY;

OFFSETを指定する場合。

    SELECT
      *
    FROM
      table
    ORDER BY column
    OFFSET 5 ROWS FETCH FIRST 10 ROWS ONLY;

感想

Oracle 12c 以降は簡潔に記述できるようになりましたが、LIMITOFFSETに比べたらまだ煩雑ですね。
なぜ統一しないんでしょう…

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?