Como posso limitar o número de filas devolvidas por uma consulta Oracle após a encomenda?

Existe uma maneira de fazer uma consulta "Oracle" comportar-se como se ela contivesse uma cláusula "MySQL limit"?

No MySQL, eu posso fazer isso:

select * 
from sometable
order by name
limit 20,10

para conseguir a 21ª a 30ª filas (saltar as primeiras 20, dar as próximas 10). As linhas são selecionadas após o ordem por, então realmente começa no 20º nome em ordem alfabética.

Em Oracle, a única coisa que as pessoas mencionam é a pseudo-coluna rownum, mas ela é avaliada antes ordenada por, o que significa isto:

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

irá devolver um conjunto aleatório de dez filas ordenadas pelo nome, que normalmente não é o que eu quero. Ele também não permite'não permite especificar um offset.

Você pode usar uma subconsulta para isso, como


select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM 
Comentários (6)

Uma solução analítica com apenas uma consulta aninhada:

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

Rank() pode ser substituído por Row_Number() mas pode retornar mais registros do que você está esperando se houver valores duplicados para o nome.

Comentários (3)

(não testado) algo como isto pode fazer o trabalho

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

Há também a classificação da função analítica, que você pode usar para fazer pedidos.

Comentários (2)