1
votes

Utilisation correcte de ROWNUM dans une requête Oracle SQL

Je veux trouver la ville et la longueur de la ville (c'est-à-dire le nombre de caractères dans le mot CITY) où la longueur de la ville est maximale dans le tableau. Au cas où nous aurions plus d'une valeur, nous ne devons prendre que la première valeur sur la base de la disposition alphabétique de la ville.

Il y a une chose étrange que j'observe:

SELECT CITY, LENGTH(CITY) FROM STATION WHERE ROWNUM = 1 ORDER BY LENGTH(CITY) DESC, CITY;

me donne le tableau correct avec la sortie souhaitée comme première ligne avec Length (City) = 21 . Mais, lorsque j'essaie de récupérer la première ligne en utilisant la requête

SELECT CITY, LENGTH(CITY) FROM STATION ORDER BY LENGTH(CITY) DESC, CITY;

dans Oracle, cela me donne une autre ligne qui a Length (City) = 12 .

S'il vous plaît, aidez-moi à comprendre ce qui ne va pas! Pour info également, il n'y a qu'une seule valeur avec la longueur maximale de la ville.


0 commentaires

3 Réponses :


4
votes

La clause WHERE de votre requête est exécutée avant ORDER BY donc le ROWNUM = 1 n'est pas la ligne attendue. Vous pouvez utiliser FETCH FIRST ROW UNIQUEMENT à la place:

SELECT * 
FROM (
  SELECT CITY, LENGTH(CITY) 
  FROM STATION 
  ORDER BY LENGTH(CITY) DESC, CITY
)x WHERE ROWNUM = 1;

... ou vous mettez l'instruction dans une sous-sélection et utilisez WHERE avec ROWNUM à ce sujet:

SELECT CITY, LENGTH(CITY) 
FROM STATION 
ORDER BY LENGTH(CITY) DESC, CITY 
FETCH FIRST ROW ONLY;

démo sur dbfiddle.uk


0 commentaires

4
votes

rownum fonctionne très bien. La clause where est traitée avant la commande order by . Vous pouvez utiliser une sous-requête à la place:

SELECT CITY, LENGTH(CITY)
FROM STATION S
ORDER BY LENGTH(CITY) DESC, CITY
FETCH FIRST 1 ROW ONLY;

Ou, mieux encore, utilisez FETCH qui est disponible dans Oracle depuis de nombreuses années:

SELECT S.*
FROM (SELECT CITY, LENGTH(CITY)
      FROM STATION S
      ORDER BY LENGTH(CITY) DESC, CITY
     ) S
WHERE ROWNUM = 1 ;


0 commentaires

2
votes

Vous pouvez également le faire comme ceci:

select city, length_city
from ( SELECT CITY
              , LENGTH(CITY) length_city
              , row_number() over(order by LENGTH(CITY) DESC, CITY) rn
       FROM STATION)
where rn =1;

Voici un petit DEMO


3 commentaires

Salut @AmitPathak, ce serait bien d'avoir vos commentaires. Vous pouvez accepter la bonne réponse et commenter si certaines des réponses ne sont pas correctes afin que nous puissions savoir pourquoi ce n'est pas correct et ensuite essayer d'aider plus ... Cheers!


Bonjour @VBoka, pouvez-vous expliquer le mot-clé over que vous avez utilisé


Bonjour @AmitPathak, voici ce que j'ai trouvé pour que je puisse vous répondre rapidement et utile: stackoverflow.com/questions/1092120/over-clause-in-oracle Veuillez dire si cela ne suffit pas