oracle : sélection des npremieres lignes :ROWNUM

oracle : sélection des npremieres lignes :ROWNUM - SQL/NoSQL - Programmation

Marsh Posté le 29-03-2006 à 11:20:10    

bonjour,
 
j'ai lu la FAQ http://oracle.developpez.com/faq/?page=11, mais malgré cela je ne parviens pas à récupérer mes premiers lignes;
 
Une requete telle que
 

Code :
  1. SELECT ROWNUM,r.*
  2. FROM(SELECT prix FROM vehicule v, marque ma,modele mo,client c
  3. WHERE ma.idmarq=mo.idmarq AND v.idmod=mo.idmod AND c.idcli=v.idcli AND mo.idmod=7 ORDER BY v.datedebutann) r
  4. WHERE ROWNUM between 1 and 1;


 
fonctionne, mais quand je rajoute d'autres champs en plus du prix, soit la meme requete avec :
 

Code :
  1. SELECT ROWNUM,r.*
  2. FROM(SELECT datedebutann,nommarq,nommod,anneevehi,carburation,kilometrevehi,couleur,prix
  3.          FROM vehicule v, marque ma,modele mo,client c
  4.          WHERE ma.idmarq=mo.idmarq AND v.idmod=mo.idmod AND c.idcli=v.idcli AND mo.idmod=7 ORDER BY v.datedebutann) r
  5. WHERE ROWNUM between 1 and 1;


 
j'obtiens l'erreur

SP2-0734: unknown command beginning "Y v.datede..." - rest of line ignored.


 
Cela pourrait venir du fait que je fais des jointures, mais pourquoi la requete est fausse ???
 
(désolé pour la complexité des requêtes!)


Message édité par ___ le 29-03-2006 à 11:34:27
Reply

Marsh Posté le 29-03-2006 à 11:20:10   

Reply

Marsh Posté le 29-03-2006 à 12:20:12    

pourquoi tu passes par une sous requetes ?

Reply

Marsh Posté le 29-03-2006 à 12:22:44    

non, c'est une erreur de syntaxe mais j'arrive pas à mettre le doigt dessus :/
 
Essaye d'ajouter les colonnes l'une après l'autre

Reply

Marsh Posté le 29-03-2006 à 12:23:15    

dlaumor a écrit :

pourquoi tu passes par une sous requetes ?


 
pour limiter le nombre de ligne en tenant compte de l'ordre... le ORDER BY est appliqué en dernier dans une requête

Reply

Marsh Posté le 29-03-2006 à 13:16:07    

une erreur de syntaxe je veux bien, mais je ne vois pas où elle pourrait etre !!!
 

Citation :

le ORDER BY est appliqué en dernier dans une requête


En dernier ? Il n'est pas fait en premier, pour qu'après le ROWNUM permette de trouver les 5 premieres (par exemple) lignes de cette requete triée ?
 
 
l'erreur de syntaxe "serait" dans la partie  "datedebutann,nommarq,nommod,anneevehi,carburation,kilometrevehi,couleur," !
 
et justement dans mon 1er post, ma 1ere requete passe mais pas la 2eme ...
avec le prix et en rajoutant seulement "anneevehi" la requete échoue, mais ce champ existe bien .

Message cité 1 fois
Message édité par ___ le 29-03-2006 à 13:19:28
Reply

Marsh Posté le 29-03-2006 à 16:07:43    

ce qu'il voulait dire c'est que t'étais justement obligé de passer par une sous-requete pour que "l'order by" se fasse avec le filtre sur ROWNUM
 
pour ton prb, si tu ne mets QUE anneevehi ça passe ?

Reply

Marsh Posté le 29-03-2006 à 17:16:04    

___ a écrit :


En dernier ? Il n'est pas fait en premier, pour qu'après le ROWNUM permette de trouver les 5 premieres (par exemple) lignes de cette requete triée ?


 
Oui le ORDER BY est la dernière chose faite lors de l'exécution d'un requête, c'est ce qui oblige à passer par une sous-requête :/
 
Tu peux utiliser RANK sinon :
http://lalystar.developpez.com/fon [...] ques/#L3.8
 

Reply

Marsh Posté le 29-03-2006 à 17:25:30    


bon en fait je n'ai pas vraiment compris quel était mon problème car je testais sous linux par compier coller; je suis revenu pâr la suite sous windows et ma requete fonctionnait ...... donc à ce niveau je n'ai plus de problème !
 
maintenant je voudrais savoir comment marche le BETWEEN (en tout cas le mien) car quand je fais un  
 
BETWEEN 1 and 1 j'ai un résultat,  
BETWEEN 1 and 2 j'ai deux résultats (1et2)
mais un BETWEEN 2 and 2 je n'ai AUCUN résultat !!!
 

Code :
  1. SELECT r.*,ROWNUM FROM(SELECT cpcli,villecli,datedebutann,nommarq,nommod,anneevehi,carburation,kilometrevehi,couleur,prix
  2.                                                    FROM vehicule v, marque ma,modele mo, client c
  3.                                                    WHERE ma.idmarq=mo.idmarq AND v.idmod=mo.idmod AND c.idcli=v.idcli AND ma.idmarq=2 ORDER BY v.datedebutann) r
  4. WHERE ROWNUM BETWEEN 2 AND 2


 
pourquoi ????

Reply

Marsh Posté le 29-03-2006 à 18:50:37    

bon aucune réponse peut-être.
 
il me semble que j'ai trouvé une solution:

Code :
  1. SELECT * FROM(SELECT r.*,ROW_NUMBER() OVER(ORDER BY 1) LINENUM
  2.                       FROM(   SELECT cpcli,villecli,datedebutann,nommarq,nommod,anneevehi,carburation,kilometrevehi,couleur,prix n
  3.                                    FROM vehicule v, marque ma,modele mo, client c
  4.                                    WHERE ma.idmarq=mo.idmarq AND v.idmod=mo.idmod AND c.idcli=v.idcli AND ma.idmarq=2 ORDER BY v.datedebutann) r
  5.                                )
  6. WHERE LINENUM BETWEEN 2 AND 2


 
:-)


Message édité par ___ le 29-03-2006 à 19:23:39
Reply

Marsh Posté le 29-03-2006 à 20:47:20    

Le rownum est incrémenté de 1 à chaque ligne renvoyée.
 
Si tu fais :
 
SELECT * FROM maTable
WHERE ROWNUM = 2;
 
ce qui se passe en interne, c'est :
- j'ai une ligne de maTable qui correspond, son rownum vaut 1, donc je la renvoie pas,
- j'ai une autre ligne de maTable qui correspond, le rownum vaut toujours 1, donc je la renvoie pas,
- etc.
 
La façon la plus performante de faire un pseudo between avec rownum est de faire :
 
select *  
  from ( select a.*, rownum rnum
           from ( YOUR_QUERY_GOES_HERE -- including the order by ) a
          where rownum <= MAX_ROWS )
 where rnum >= MIN_ROWS;
 
C'est plus performant que ta requête, car Oracle détecte qu'il n'y a pas besoin de parser toute la table, on peut s'arrêter aux première données triées ;)

Reply

Marsh Posté le 29-03-2006 à 20:47:20   

Reply

Marsh Posté le 30-03-2006 à 10:31:40    

Dans certains cas, c'est encore plus performant d'utiliser RANK () OVER
 

Code :
  1. select * from (
  2. select <colonnes à sélectionner>, RANK() OVER (order by <tuple unique : la PK en principe> ) a from <ta table> )
  3. where  a  between <borne inf> and <borne sup>;


 
Dans ta requête :

Code :
  1. select * from (
  2. SELECT cpcli,villecli,datedebutann,nommarq,nommod,anneevehi,carburation,kilometrevehi,couleur,prix n, , RANK() OVER (order by v.datedebutann) r
  3.                                   FROM vehicule v, marque ma,modele mo, client c
  4.                                   WHERE ma.idmarq=mo.idmarq AND v.idmod=mo.idmod AND c.idcli=v.idcli AND ma.idmarq=2
  5.                  )
  6. where  r  between <borne inf> and <borne sup>;

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed