注文後の Oracle クエリで返される行数を制限するには?

Oracle」のクエリが「MySQL」の「limit」句を含んでいるように動作させる方法はありますか?

MySQL`ではこのようなことができます。

select * 
from sometable
order by name
limit 20,10

とすると、21行目から30行目までを取得することができます(最初の20行はスキップして、次の10行を取得します)。行は order by の後に選択されるので、実際にはアルファベット順で20番目の名前から始まります。

Oracleでは、rownumという疑似カラムだけが言及されていますが、これはorder by` の前*に評価されるので、次のようになります。

select * 
from sometable
where rownum <= 10
order by name

は名前順に並んだ10行のランダムなセットを返しますが、これは通常私が望むものではありません。また、オフセットを指定することもできません。

これには、次のようなサブクエリを使用できます。


select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM 
解説 (6)

1つのネストされたクエリのみを使用した分析的ソリューション。

SELECT * FROM
(
   SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
) 
WHERE MyRow BETWEEN 10 AND 20;

Row_Number()の代わりにRank()を使うこともできますが、nameに重複した値がある場合、期待したよりも多くのレコードを返すかもしれません。

解説 (3)

(試していませんが、このようなものが仕事をするかもしれません。

WITH
base AS
(
    select *                   -- get the table
    from sometable
    order by name              -- in the desired order
),
twenty AS
(
    select *                   -- get the first 30 rows
    from base
    where rownum < 30
    order by name              -- in the desired order
)
select *                       -- then get rows 21 .. 30
from twenty
where rownum > 20
order by name                  -- in the desired order

また、解析的な関数であるrankもあり、これを使って順序付けすることができます。

解説 (2)