ROWNUM, LIMIT, FETCH FIRST n ROW(S) ONLY
Il est parfois intéressant de limiter le nombre de résultats retournés par le SGBD pour une requête particulière. Certes, il est toujours possible de demander le jeu de résultats complet puis de nafficher que les premiers résultats. Mais, si un ensemble fixé de résultats est requis et que lon se moque des autres résultats, il est plus performant de faire le travail en amont.
Les utilisateurs dOracle utilisent souvent pour cela ROWNUM, une pseudo-colonne attribuant un numéro à chaque ligne du jeu de résultats. Ajouter rownum < 4 à votre clause WHERE permettra ainsi de ne renvoyer que 3 résultats.
ROWNUM est spécifique Oracle mais avec dautres SGBD, comme dailleurs PostgreSQL, vous utilisez parfois le mot clé LIMIT. Toutes ces syntaxes ne sont pas standard SQL. Pour revenir à ROWNUM, une mauvaise compréhension de son fonctionnement peut même entraîner un problème de résultats faux.
Nous allons ici considérer une table contenant 10 lancers, il s'agit de ramener les 3 meilleurs, triés par performance décroissante :
Cela renvoie un résultat mais pas du tout celui attendu. Le tri est opéré APRES le filtrage par rownum. Nous avons donc renvoyé les 3 premiers résultats qui venaient puis ils ont été triés.
Voici l'écriture correcte avec rownum :
Cette écriture n'est pas standard SQL de toute façon. Comment écrire cette requête en SQL ? La norme SQL-2008 donne la réponse : utilisez FETCH FIRST n ROW(S) ONLY. Illustration avec PostgreSQL 13 beta mais PostgreSQL respecte la norme sur ce point depuis la version 8.4 sortie en 2009 :
Microsoft SQL Server comprend cette syntaxe depuis la version 2012 et Oracle Database depuis la version 12.1. Illustration avec Oracle 19c :
Vous pouvez souhaiter avoir les 3 meilleures performances mais connaître les ex aequo au dernier rang. Pour cela, PostgreSQL intègre depuis la version 13 la syntaxe "WITH TIES" à utiliser au lieu de "ONLY". Illustration avec PostgreSQL 13 beta :
Cette syntaxe est également connue d'Oracle Database depuis la version 12.1, illustration toujours avec Oracle 19c :
Voilà, vous avez tous les moyens d'écrire vos requêtes top-N avec du code SQL standard compris par de nombreux SGBD.
Mise à jour : 21/05/2020