Coding Interview Prep · Leçon

RANK ou DENSE_RANK en cas d’égalité

La question classique sur le classement avec ou sans saut lorsqu’il y a égalité de valeurs

Leçon 3 sur 413 étapes

RANK ou DENSE_RANK en cas d’égalité est une leçon Coding Interview Prep gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Coding Interview Prep, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Coding Interview Prep comprend 4 leçons au total.

Les trois fonctions de classement côte à côte

SQL propose trois fonctions de classement de fenêtre, et la question sur les fenêtres la plus fréquemment posée concerne la différence de leur comportement en cas d'égalité :

  • ROW_NUMBER — toujours unique ; les valeurs à égalité reçoivent des numéros distincts et arbitraires.
  • RANK — les valeurs à égalité partagent un classement, puis le classement suivant saute (il laisse un trou).
  • DENSE_RANK — les valeurs à égalité partagent un classement, puis le classement suivant ne saute pas (aucun trou).

Être capable d'énoncer instantanément cette distinction est un indicateur fiable en entretien.

Un tableau d'exemple concret

Imaginez cinq scores triés par ordre décroissant : 100, 90, 90, 80, 70. Observez comment chaque fonction les numérote.

  • ROW_NUMBER : 1, 2, 3, 4, 5
  • RANK : 1, 2, 2, 4, 5 (saute 3 après l'égalité)
  • DENSE_RANK : 1, 2, 2, 3, 4 (aucun saut)

Mémorisez cet exemple 100/90/90/80/70 : il permet de répondre immédiatement à la question.

SELECT
  score,
  ROW_NUMBER()  OVER (ORDER BY score DESC) AS rownum,
  RANK()        OVER (ORDER BY score DESC) AS rnk,
  DENSE_RANK()  OVER (ORDER BY score DESC) AS dense
FROM scores;

Comment RANK calcule le trou

RANK attribue à chaque ligne un classement égal à un plus le nombre de lignes qui la précèdent strictement dans l'ordre. Les deux lignes à égalité avec la valeur 90 sont chacune précédées par une ligne (la valeur 100), et reçoivent donc toutes deux le classement 2. La valeur suivante, plus basse, est précédée par trois lignes et passe donc directement au classement 4.

C'est pourquoi RANK reproduit un classement de compétition : plusieurs médaillés d'argent à égalité, mais aucun médaillé de bronze.

-- scores 100,90,90,80 -> RANK = 1,2,2,4
SELECT score, RANK() OVER (ORDER BY score DESC) AS rnk
FROM scores;

Comment DENSE_RANK évite le trou

DENSE_RANK attribue un classement égal à un plus le nombre de valeurs distinctes qui précèdent la valeur actuelle. Après l'égalité à 90, seules deux valeurs distinctes précèdent le 80 (100 et 90), qui reçoit donc le classement 3 — sans trou.

Utilisez DENSE_RANK lorsque vous vous intéressez à la position de valeurs distinctes, par exemple pour obtenir « le deuxième salaire le plus élevé » en comptant les égalités une seule fois.

-- scores 100,90,90,80 -> DENSE_RANK = 1,2,2,3
SELECT score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense
FROM scores;

Quand choisir chaque fonction

Un guide de décision rapide que les recruteurs aiment entendre :

  • Vous avez besoin d'une seule ligne par position (dernier enregistrement, pagination) ? → ROW_NUMBER.
  • Vous avez besoin d'un classement où les égalités partagent le même rang et où les sauts sont corrects (classement sportif, trois premiers en incluant les égalités) ? → RANK.
  • Vous avez besoin de la N-ième valeur distincte (le N-ième salaire le plus élevé) ? → DENSE_RANK.

Un mauvais choix modifie les lignes que vous renvoyez : justifiez donc votre choix à voix haute.

Classement au sein des partitions

Les trois fonctions acceptent PARTITION BY pour effectuer le classement indépendamment dans chaque groupe. Chaque partition recommence au rang 1.

Ici, chaque service classe ses propres employés selon leur salaire, avec les égalités gérées par DENSE_RANK. La personne la mieux rémunérée de chaque service obtient le rang 1, et les employés ayant le même salaire partagent un rang.

SELECT
  department,
  name,
  salary,
  DENSE_RANK() OVER (
    PARTITION BY department
    ORDER BY salary DESC
  ) AS salary_rank
FROM employees;

Exemple détaillé : les trois premiers en incluant les égalités

« Renvoyez les trois salaires les plus élevés par service et, si plusieurs personnes sont à égalité au troisième rang, incluez-les toutes. » Cela nécessite RANK ou DENSE_RANK, et non ROW_NUMBER.

Utiliser DENSE_RANK <= 3 conserve les trois niveaux de salaire distincts les plus élevés ainsi que chaque employé appartenant à ces niveaux — c'est exactement ce que signifie « en incluant les égalités ».

SELECT department, name, salary, salary_rank
FROM (
  SELECT department, name, salary,
         DENSE_RANK() OVER (
           PARTITION BY department ORDER BY salary DESC
         ) AS salary_rank
  FROM employees
) t
WHERE salary_rank <= 3;

Exemple détaillé : le deuxième salaire le plus élevé

La question d'entretien SQL la plus célèbre. La réponse robuste utilise DENSE_RANK, afin que les salaires maximaux en double ne rendent pas la vraie deuxième valeur inaccessible.

Si trois personnes perçoivent le salaire maximal, DENSE_RANK = 2 identifie toujours correctement le salaire distinct suivant, tandis que ROW_NUMBER = 2 renverrait simplement une autre personne ayant le salaire maximal.

SELECT DISTINCT salary AS second_highest
FROM (
  SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS dr
  FROM employees
) t
WHERE dr = 2;

RANK et DENSE_RANK pour la N-ième valeur la plus élevée

Pourquoi préférer DENSE_RANK à RANK pour les problèmes de N-ième valeur la plus élevée ? Parce que RANK laisse des sauts. Avec les salaires 100, 100, 90, la valeur 90 a RANK = 3, mais DENSE_RANK = 2.

Si la question demande le « 2e salaire distinct le plus élevé », filtrer avec RANK = 2 ne renverrait rien, tandis que DENSE_RANK = 2 renverrait correctement 90. Associez toujours « N-ième valeur distincte » à DENSE_RANK.

-- salaries 100,100,90
-- RANK:       1,1,3   -> WHERE rank = 2 returns NOTHING
-- DENSE_RANK: 1,1,2   -> WHERE dense_rank = 2 returns 90

Notes selon les dialectes

Bonne nouvelle : ROW_NUMBER, RANK et DENSE_RANK sont définies par le standard SQL et se comportent de manière identique dans PostgreSQL, SQL Server, Oracle, MySQL 8+, BigQuery et Snowflake. La gestion des égalités présentée plus haut est universelle.

Une fonction apparentée, PERCENT_RANK, s'appuie sur RANK pour fournir une position relative comprise entre 0 et 1 — cela mérite d'être mentionné si un recruteur vous interroge sur le classement en percentile.

Erreurs fréquentes

Soyez attentif aux points suivants :

  • Utiliser ROW_NUMBER pour la « N-ième valeur la plus élevée » et omettre les lignes à égalité.
  • Utiliser RANK lorsque la question porte sur des valeurs distinctes, puis obtenir un résultat vide à cause des sauts.
  • Oublier ORDER BY dans OVER : un classement n'a aucun sens sans lui.
  • Filtrer directement le classement dans WHERE au lieu de le faire dans une requête externe.

Vérification rapide

Appliquez les règles de gestion des égalités.

Récapitulatif : avec ou sans sauts

Vous pouvez désormais choisir instantanément la bonne fonction de classement :

  • ROW_NUMBER : des nombres uniques, aucun rang partagé.
  • RANK : les égalités partagent un rang, puis un saut est laissé (1,2,2,4).
  • DENSE_RANK : les égalités partagent un rang, sans saut (1,2,2,3).
  • « N-ième valeur distincte la plus élevée » → DENSE_RANK ; « les N premières en incluant les égalités » → RANK/DENSE_RANK ; « une ligne par position » → ROW_NUMBER.

Ensuite : comment filtrer réellement sur un résultat de fenêtre, puisque vous ne pouvez pas le faire dans WHERE.

Gratuit pour commencer

Apprends Coding Interview Prep avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
90
Leçons
360

Questions Fréquemment Posées

La leçon « RANK ou DENSE_RANK en cas d’égalité » est-elle gratuite ?

Oui — le texte complet de « RANK ou DENSE_RANK en cas d’égalité » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Coding Interview Prep, passe à CoddyKit PRO. Le cours Coding Interview Prep comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « RANK ou DENSE_RANK en cas d’égalité » ?

La question classique sur le classement avec ou sans saut lorsqu’il y a égalité de valeurs Tu pratiques Coding Interview Prep avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Coding Interview Prep ?

Aucune expérience préalable n'est requise. Coding Interview Prep sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « RANK ou DENSE_RANK en cas d’égalité » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Coding Interview Prep ?

Oui. Chaque leçon Coding Interview Prep inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. OVER, PARTITION BY et ORDER BY
  2. ROW_NUMBER pour une numérotation unique
  3. RANK ou DENSE_RANK en cas d’égalité
  4. Filtrer sur un résultat de fenêtre
← Retour à Coding Interview Prep