Les requêtes Top-N et la pagination sont courantes dans les applications Web. L'utilisateur entre un ensemble de critères, qui exécute une requête, puis permet à l'utilisateur de cliquer sur les boutons Précédent et Suivant pour parcourir l'ensemble de résultats. Pour obtenir cette fonctionnalité de pagination, l'application doit pouvoir obtenir un certain ensemble de lignes à partir de la requête de base de données.
Jetons un coup d'œil aux différentes méthodes dans Oracle pour réaliser les requêtes Top-N dans Oracle et la pagination dans la requête Oracle
Pré 12c
(1) Utilisation de la clause ROWNUM
Qu'est-ce que ROWNUM
C'est une pseudo-colonne (pas une vraie colonne) qui est disponible dans une requête. ROWNUM se verra attribuer les nombres 1, 2, 3, 4, … N , où N est le nombre de lignes dans l'ensemble ROWNUM est utilisé avec. Une valeur ROWNUM n'est pas affectée de façon permanente à une ligne .
Voici comment obtenir les 5 premières valeurs
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Cette version triera Dept par ventes en ordre décroissant, puis renverra les cinq premiers enregistrements rencontrés (les cinq premiers enregistrements).
Pour la pagination dans oracle , si vous souhaitez que les 5 à 10 enregistrements du Dept soient triés par desc de ventes, puis allez-y.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
La syntaxe générale serait
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) Utilisation de la fonction analytique oracle ROW_NUMBER() :elle se comporte de la même manière que la pseudo-colonne ROWNUM mais est plus flexible et a plus de capacités
Voici comment obtenir les 5 premières valeurs
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Voici la requête pour Pagination
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;
Les requêtes Top N ci-dessus renverront des enregistrements différents lorsque deux éléments sont à égalité lors de l'utilisation des requêtes Top n
(3) Utilisation de RANK() et DENSE_RANK() :il s'agit de fonctions analytiques qui peuvent être utilisées pour résoudre le problème mentionné ci-dessus
Voici comment obtenir les 5 premières valeurs à l'aide de rank
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Voici comment obtenir les 5 premières valeurs en utilisant dense_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Avec 12c
Fonctionnalité Top-N :
Oracle Database 12c inclut la prise en charge des clauses FETCH FIRST/NEXT et OFFSET de la norme ANSI, appelées ensemble la clause de limitation de ligne. Cette clause vous permet de récupérer facilement les N premiers enregistrements d'un ensemble de résultats ou, alternativement, les N premiers enregistrements après avoir sauté un ensemble d'enregistrements, de sorte que vous pouvez facilement paginer dans un ensemble de résultats
Une requête Top-N nous permet de récupérer les N premières ou dernières lignes d'un ensemble ordonné. La combinaison de deux requêtes Top-N vous permet de parcourir un ensemble ordonné
Exemple :
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;
Si vous regardez le plan d'optimisation pour la requête ci-dessus, il utilise toujours row_number() sous le capot pour le faire
La pagination peut également se produire avec cette fonctionnalité avec l'utilisation de la syntaxe offset
– offset 10 lignes récupérer les 10 premières lignes uniquement
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– décalage de 10 lignes pour récupérer uniquement les 0,1 % de premières lignes
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– décalage de 10 lignes pour récupérer les 3 premières lignes avec des liens. Cela signifie que toutes les lignes du haut avec des liens seront également incluses dans le résultat
select * from my_test order by name fetch first 3 rows with ties;
Si vous vérifiez le plan d'optimisation de la requête ci-dessus, vous constaterez que l'optimiseur utilise la fonction rank() comme démontré ci-dessus dans le cas Pre 12c
Restriction
(1)Si vous avez une instruction SELECT avec FOR UPDATE, vous ne pouvez pas l'utiliser.
(2)L'instruction SELECT ne peut pas CURRVAL ou NEXTVAL de séquences
(3) Si la requête des vues matérialisées contient cette clause, vous ne pouvez pas effectuer d'actualisation incrémentielle de cette vue matérialisée
J'espère que vous aimez l'article sur les requêtes Top-N dans oracle et la pagination dans la requête oracle. Merci de nous faire part de vos commentaires
Lit également
Fonction Lead dans Oracle
Fonction RANK dans Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html