RANK Oracle : Fonction de Classement SQL Expliquée

Découvrez la fonction RANK en Oracle SQL : définition, syntaxe, exemples pratiques et erreurs courantes. Maîtrisez le classement de vos données facilement.

Illustration du tutoriel SQL Oracle : RANK Oracle : Fonction de Classement SQL Expliquée

Publicité

🧪 Envie de pratiquer ? Exécutez les exemples de cet article dans notre SQL Playground gratuit — aucun logiciel à installer.

La fonction RANK en Oracle SQL : classement et analyse de données

La fonction RANK en Oracle SQL est une fonction analytique puissante qui permet d’attribuer un rang à chaque ligne d’un ensemble de résultats, en fonction d’un critère de tri défini. Utilisée dans des contextes métier variés — ressources humaines, finance, e-commerce — la fonction RANK est indispensable pour produire des classements pertinents et fiables directement dans vos requêtes SQL Oracle.

Définition et utilisation de RANK

La fonction RANK est une fonction de fenêtrage analytique (aussi appelée window function) introduite par Oracle pour répondre aux besoins de classement dans les ensembles de données. Elle attribue un rang entier à chaque ligne selon un ordre précis. Sa caractéristique principale : en cas d’égalité, plusieurs lignes peuvent obtenir le même rang, et le rang suivant tient compte du nombre de lignes ex æquo (on parle de « saut de rang »).

Par exemple, si deux employés partagent le rang 3, le prochain rang attribué sera 5 (et non 4). Ce comportement la distingue de DENSE_RANK, qui ne crée pas de saut.

Cas d’usage en entreprise

  • Ressources humaines : classer les salariés par salaire au sein d’un département.
  • Commercial : identifier les meilleurs vendeurs du mois par région.
  • Finance : classer les produits financiers par performance.
  • E-commerce : afficher le top des produits les plus vendus par catégorie.

Syntaxe de la fonction RANK

Oracle propose deux modes d’utilisation pour RANK : en tant que fonction analytique (avec la clause OVER) et en tant que fonction agrégée hypothétique. Dans la grande majorité des cas, c’est la forme analytique qui est utilisée.

Forme analytique

RANK() OVER (
  [PARTITION BY colonne1, colonne2, ...]
  ORDER BY colonne3 [ASC | DESC], ...
)

Explication des paramètres

  • RANK() : appel de la fonction, sans argument.
  • OVER (...) : définit la fenêtre d’analyse sur laquelle la fonction s’applique.
  • PARTITION BY (optionnel) : divise le jeu de résultats en partitions indépendantes. Le classement redémarre à 1 pour chaque partition. Si omis, toute la table est traitée comme une seule partition.
  • ORDER BY (obligatoire) : définit le critère de tri utilisé pour établir le rang. Sans cet élément, la requête est invalide.

Forme agrégée hypothétique

RANK(valeur1, valeur2, ...) WITHIN GROUP (ORDER BY colonne1, colonne2, ...)

Cette forme permet de calculer le rang qu’obtiendrait une valeur hypothétique si elle était insérée dans le groupe. Elle est moins fréquente mais utile pour des simulations.

Exemples pratiques de RANK en Oracle SQL

Exemple 1 — Classement des employés par salaire dans chaque département

Contexte métier : Une DRH souhaite établir un classement des salaires au sein de chaque département pour préparer les revues annuelles de rémunération.

-- Classement des employés par salaire décroissant, par département
SELECT
    employee_id,
    last_name,
    department_id,
    salary,
    RANK() OVER (
        PARTITION BY department_id   -- Redémarre le classement pour chaque département
        ORDER BY salary DESC          -- Les plus hauts salaires en premier
    ) AS rang_salaire
FROM employees
ORDER BY department_id, rang_salaire;

Résultat attendu (extrait) :

EMPLOYEE_ID  LAST_NAME   DEPARTMENT_ID  SALARY   RANG_SALAIRE
-----------  ----------  -------------  -------  ------------
101          King        10             10000    1
102          Blake       10             9000     2
103          Clark       10             9000     2
104          Jones       10             7000     4   -- Saut de rang car deux ex æquo au rang 2

On remarque le saut de rang caractéristique de RANK : après deux employés au rang 2, le suivant passe directement au rang 4.

Exemple 2 — Top 3 des produits les plus vendus par catégorie

Contexte métier : Un responsable e-commerce souhaite afficher les 3 articles les plus vendus dans chaque catégorie de produits pour alimenter un tableau de bord de performance.

-- Sélection des 3 meilleurs produits par catégorie selon le chiffre de ventes
SELECT *
FROM (
    SELECT
        p.product_id,
        p.product_name,
        p.category_id,
        SUM(od.quantity) AS total_vendu,
        RANK() OVER (
            PARTITION BY p.category_id    -- Un classement par catégorie
            ORDER BY SUM(od.quantity) DESC -- Les plus vendus d'abord
        ) AS rang_ventes
    FROM products p
    JOIN order_details od ON p.product_id = od.product_id
    GROUP BY p.product_id, p.product_name, p.category_id
)
WHERE rang_ventes <= 3   -- On garde uniquement le top 3
ORDER BY category_id, rang_ventes;

Ce type de requête imbriquée est très courant en Oracle : la fonction analytique est calculée dans la sous-requête, puis le filtre WHERE est appliqué dans la requête externe, car on ne peut pas filtrer directement sur un alias de fonction analytique.

Publicité

Erreurs courantes avec RANK

Erreur : utiliser WHERE pour filtrer directement sur le rang

Une erreur fréquente chez les développeurs SQL débutants consiste à filtrer sur le résultat de RANK() directement dans la clause WHERE de la même requête :

-- ❌ Requête incorrecte : ORA-00904 ou résultat inattendu
SELECT
    employee_id,
    salary,
    RANK() OVER (ORDER BY salary DESC) AS rang
FROM employees
WHERE rang <= 5;  -- Erreur : l'alias 'rang' n'est pas encore calculé à ce stade

Explication : En SQL Oracle, la clause WHERE est évaluée avant les fonctions analytiques. L’alias rang n’existe donc pas encore lors du filtrage.

Solution : Encapsuler la requête dans une sous-requête (ou utiliser un CTE avec WITH) :

-- ✅ Requête correcte avec sous-requête
SELECT *
FROM (
    SELECT
        employee_id,
        salary,
        RANK() OVER (ORDER BY salary DESC) AS rang
    FROM employees
)
WHERE rang <= 5;

Résumé

Point cléDétail
Type de fonctionAnalytique (window function)
Gestion des ex æquoMême rang attribué + saut de rang suivant
Clause obligatoireORDER BY dans OVER()
Clause optionnellePARTITION BY pour des classements par groupe
Différence avec DENSE_RANKDENSE_RANK ne crée pas de saut de rang
Filtrage sur le rangToujours via une sous-requête ou un CTE
Compatible OracleOui, depuis Oracle 8i

Deux bonnes pratiques Oracle

  1. Toujours utiliser PARTITION BY lorsque vos données sont organisées en groupes logiques (département, catégorie, région) : cela évite un classement global non pertinent et améliore les performances sur de grandes tables.
  2. Préférer les CTEs (WITH) aux sous-requêtes imbriquées pour filtrer sur le rang : le code est plus lisible, plus maintenable et Oracle les optimise efficacement.

Aller plus loin

Pour approfondir votre maîtrise des fonctions analytiques Oracle, voici trois sujets complémentaires qui vous permettront de progresser :

Sur le même thème

Un nouveau tutoriel SQL par semaine

Nous ne spammons pas ! Consultez notre politique de confidentialité pour plus d’informations.

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité