Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Consultas e paginação Top-N no Oracle


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