Consultas Top-N e paginação são comuns em aplicativos baseados na Web. O usuário insere um conjunto de critérios, que executa uma consulta e permite que o usuário clique nos botões Anterior e Próximo para percorrer o conjunto de resultados. Para obter essa funcionalidade de paginação, o aplicativo precisa ser capaz de obter um determinado conjunto de linhas da consulta do banco de dados.
Vamos dar uma olhada no método diferente no Oracle para obter consultas Top-N no Oracle e paginação na consulta Oracle
Pré 12c
(1) Usando a Cláusula ROWNUM
O que é ROWNUM
É uma pseudocoluna (não uma coluna real) que está disponível em uma consulta. ROWNUM serão atribuídos os números 1, 2, 3, 4, … N , onde N é o número de linhas no conjunto com o qual ROWNUM é usado. Um valor ROWNUM não é atribuído permanentemente a uma linha.
Aqui está a maneira de obter os 5 principais valores
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Esta versão classificará Dept por vendas decrescentes e, em seguida, retornará os primeiros cinco registros encontrados (os cinco principais registros).
Para paginação no oracle , se você quiser os registros de 5 a 10 do Dept order by sales desc, então ir para isso.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
A sintaxe geral seria
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) Usando a função analítica do oráculo ROW_NUMBER():Ela se comporta de maneira semelhante à pseudocoluna ROWNUM, mas é mais flexível e tem mais recursos
Aqui está a maneira de obter os 5 principais valores
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Aqui está a consulta para paginação
SELECT * FROM ( SELECT d.*, row_number() over (ORDER BY d.sales DSC) rn FROM dept d) WHERE rn BETWEEN 0 AND 5 ORDER BY rn;
As consultas Top N acima retornarão registros diferentes quando duas coisas estiverem empatadas no local ao usar as consultas n principais
(3) Usando RANK() e DENSE_RANK():Estas são funções analíticas que podem ser usadas para remover o problema mencionado acima
Aqui está a maneira de obter os 5 principais valores usando rank
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Aqui está a maneira de obter os 5 principais valores usando denso_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Com 12c
Recurso Top-N :
O Oracle Database 12c inclui suporte para as cláusulas FETCH FIRST/NEXT e OFFSET do padrão ANSI — juntas chamadas de cláusula de limitação de linha. Esta cláusula permite que você recupere facilmente os primeiros N registros de um conjunto de resultados ou, alternativamente, os primeiros N registros após pular um conjunto de registros, para que você possa paginar facilmente um conjunto de resultados
Uma consulta Top-N nos permite recuperar as N linhas superiores ou inferiores de um conjunto ordenado. A combinação de duas consultas Top-N oferece a capacidade de percorrer um conjunto ordenado
Exemplo:
SELECT value FROM mytable ORDER BY value DESC FETCH FIRST 10 ROWS ONLY; select * from my_test order by name fetch first 3 rows only;
Se você observar o plano do otimizador para a consulta acima, ele ainda está usando row_number() sob o envoltório para fazê-lo
A paginação também pode acontecer com este recurso com a sintaxe de deslocamento de uso
– deslocamento de 10 linhas busca apenas as primeiras 10 linhas
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– deslocamento de 10 linhas busca apenas as primeiras linhas de 0,1 por cento
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– deslocamento de 10 linhas para buscar as primeiras 3 linhas com empates. Isso significa que todas as linhas superiores com empates também serão incluídas no resultado
select * from my_test order by name fetch first 3 rows with ties;
Se você verificar o plano do otimizador da consulta acima, descobrirá que o otimizador está usando a função rank() como demonstrado acima no caso Pre 12c
Restrição
(1)Se você tiver uma instrução SELECT com FOR UPDATE, não poderá usá-la.
(2)A instrução SELECT não pode CURRVAL ou NEXTVAL de sequências
(3) Se a consulta das Materialized Views tem esta cláusula, então você não pode fazer uma atualização incremental dessa Materialized View
Espero que goste do artigo sobre Consultas Top-N no oracle e Paginação na consulta do oracle. Por favor, forneça feedback
Também lê
Função principal no Oracle
Função RANK no Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html