31 mai 2007

Simuler un LIMIT sous Oracle avec ROWNUM

Je suis une adepte de MySQL alors quand je passe sous Oracle, je me demande comment récupérer des résultats compris entre x et y? Petit clin d'oeil au LIMIT de MySQL.

A quoi ça sert? Cela peut servir par exemple pour paginer des résultats.

SELECT * from
              (select champRecherche, ROWNUM AS R from tableRecherche where vosCriteresDeRecherche)
WHERE R BETWEEN x and y;

Concrètement, votre requête normale correspond à la requête en italique, auquelle vous ajoutez le champ ROWNUM AS R. Ce champ a pour but de numéroter vos résultats. Vous avez ensuite une requête externe qui récupère les résultats entre x et y.

Exemple : je recherche des élèves qui ont 18 de moyenne et je récupère les noms entre le 10eme et le 15eme élève.
select * from
             ( select nom, ROWNUM as R from ClassePremiereS where moyenne = 18 )
where R between 10 and 16;

Posté par fatihaelh à 16:31 - SQL - Commentaires [6] - Permalien [#]

Commentaires

    version ameliorée

    En fait l'attribut rownum peut etre utilisé meme si il n est pas declaré, ce qui donne:

    select champRecherche from tableRecherche where vosCriteresDeRecherche
    AND ROWNUM BETWEEN x and y;

    La partie a rajouté est en majuscule.

    Merci Fatiha,c est en bidouillant a partir de ton exemple que je m'en suis rendu compte. @+

    Chris.

    Posté par chris, 17 octobre 2007
  • Merci pour l'info, la requête devient plus lisible à présent

    @+

    Posté par Fatiha, 18 octobre 2007
  • Version complète

    2 choses :
    - le rownum utilisé directement comme ça ne fonctionne que si l'on part du début (x=1). Sinon, bug. Pour contourner ça, il faut encapsuler la requête avec une autre qui fera le filtre avec x!=1.
    - le rownum pose un problème pour une requête avec un order by. La numérotation a lieu avant le tri, et les numéros ne se suivent plus. Pour éviter ça, il faut encore encapsuler dans une sous requête la requete avec le order by, et laisser la numérotation au dessus.
    Au final, on obtient :
    SELECT * FROM ( SELECT ROWNUM AS rn, t.* FROM ( SELECT ... order by ...) t) WHERE rn > 20 AND rn <= 30;
    Gros pb : les temps de traitement sont monstrueux.
    Si vous avez un meilleur moyen...

    Posté par TiCi, 05 novembre 2007
  • merci bocou

    wala el adim, merci bocou, cela fait 2 jour que je creuse dessus et rien jusqu'à aujourd'hui. je suis passé à oracle, on m'a pas laissé le choix ( à bientot mysql) pour un projet en interne. si g d soucis je te recontact, ok, à bientot, et quell Ouverture!!

    Posté par halimix, 06 novembre 2008
  • Bravo

    Bravo TiCi pour la requête, ça contourne bien le probleme

    Posté par Dyl, 06 mai 2010
  • Merci

    Merci, ça marche =)

    Posté par Robert, 29 juin 2011

Poster un commentaire