Le plus gros salaire par service
Combiner partitionnement et classement pour résoudre les problèmes de salaire maximal par groupe
Le plus gros salaire par service 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.
Du classement global au classement par groupe
Passons à la question suivante : « Trouvez l’employé le mieux payé de chaque service. » Elle combine classement et regroupement et constitue une question incontournable de niveau intermédiaire.
Supposons une table employee contenant id, name, department_id et salary. Nous voulons obtenir la personne la mieux rémunérée de chaque service — ou plusieurs personnes en cas d’égalité — et non simplement le maximum global.
Le nouvel outil essentiel est PARTITION BY, qui recommence le classement dans chaque service.
CREATE TABLE employee (
id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT,
salary INT
);PARTITION BY réinitialise le classement
Ajouter PARTITION BY department_id à la fenêtre indique à la base de données de calculer le classement indépendamment dans chaque service.
Chaque service commence avec son propre rang 1. Ainsi, l’employé le mieux payé du service 1 et celui du service 5 obtiennent tous deux le rang 1. Sans partitionnement, seul le maximum global obtiendrait le rang 1.
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee;Filtrer sur le rang 1
Pour ne conserver que les personnes les mieux rémunérées, encapsulez la requête classée, puis filtrez sur le rang 1. Comme toujours, la fonction de fenêtre doit être calculée dans une sous-requête ou un CTE avant de pouvoir filtrer dessus.
Utiliser DENSE_RANK ou RANK ici signifie que, si deux employés ont le même salaire maximal dans un service, les deux sont renvoyés. C’est généralement l’interprétation correcte de « la personne la mieux rémunérée ».
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee
) t
WHERE rnk = 1;ROW_NUMBER lorsque vous voulez exactement une ligne
Parfois, l'intervieweur veut exactement une ligne par département, même en cas d'égalité. Utilisez alors ROW_NUMBER et ajoutez un critère de départage déterministe, comme l'identifiant le plus bas.
Sans ce critère, les égalités sont résolues arbitrairement et votre résultat n'est pas déterministe. L'ajout de , id ASC rend le choix reproductible.
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
ROW_NUMBER() OVER (
PARTITION BY department_id
ORDER BY salary DESC, id ASC
) AS rn
FROM employee
) t
WHERE rn = 1;DENSE_RANK, ROW_NUMBER ou RANK ici
Choisissez selon la formulation exacte :
- DENSE_RANK = 1: tous les employés à égalité pour le salaire le plus élevé de chaque département.
- RANK = 1: identique à DENSE_RANK pour le premier rang (les écarts ne comptent qu'en dessous du rang 1).
- ROW_NUMBER = 1: exactement un employé par département, les égalités étant départagées par votre ORDER BY.
Ce que les intervieweurs évaluent, c'est que vous indiquiez lequel vous avez choisi et pourquoi.
L'approche corrélée avant les fonctions de fenêtre
Avant les fonctions de fenêtre, la solution standard consistait à utiliser une sous-requête corrélée : ne conserver une ligne que si personne dans le même département ne gagne davantage.
Cette méthode renvoie naturellement tous les employés les mieux rémunérés à égalité. Elle est portable, mais peut être lente, car le MAX interne est évalué pour chaque ligne externe, à moins que l'optimiseur ne réécrive la requête.
SELECT e.name, e.department_id, e.salary
FROM employee e
WHERE e.salary = (
SELECT MAX(e2.salary)
FROM employee e2
WHERE e2.department_id = e.department_id
);L'approche par jointure avec GROUP BY
Autre méthode portable : calculer le salaire maximal par département avec GROUP BY, puis effectuer une jointure pour récupérer les employés correspondants.
Cette approche est efficace et claire. La jointure ramène chaque employé dont le salaire est égal au maximum de son département, les égalités sont donc conservées.
SELECT e.name, e.department_id, e.salary
FROM employee e
JOIN (
SELECT department_id, MAX(salary) AS max_sal
FROM employee
GROUP BY department_id
) m
ON e.department_id = m.department_id
AND e.salary = m.max_sal;Les N salariés les mieux rémunérés par département
Ce schéma s'étend aux « 3 salariés les mieux rémunérés par département » sans introduire de nouvelle idée. Modifiez simplement le filtre pour utiliser un intervalle.
Avec DENSE_RANK, rnk <= 3 renvoie les trois niveaux de salaire distincts les plus élevés (et éventuellement plus de trois lignes en cas d'égalité). Avec ROW_NUMBER, rn <= 3 renvoie exactement trois lignes par département.
SELECT name, department_id, salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee
) t
WHERE rnk <= 3;Exemple détaillé
Département 1 : Ana 120, Bob 120, Cara 90. Département 2 : Dan 200, Eve 150.
- DENSE_RANK = 1: Ana (120) et Bob (120) du département 1 ; Dan (200) du département 2. Trois lignes.
- ROW_NUMBER = 1 avec l'identifiant comme critère de départage: l'un d'Ana ou de Bob (celui dont l'identifiant est le plus bas), ainsi que Dan. Deux lignes.
Les mêmes données peuvent produire un nombre de lignes différent selon la fonction. Choisissez-la en fonction de la question.
Inclure les départements et joindre leurs noms
Les intervieweurs ajoutent souvent une table department et demandent le nom du département. Il suffit de la joindre après le classement.
Conservez le classement sur la table employee et joignez la table de référence à la fin, afin que le partitionnement s'effectue toujours à la bonne granularité.
SELECT d.name AS department, t.name AS employee, t.salary
FROM (
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id ORDER BY salary DESC
) AS rnk
FROM employee
) t
JOIN department d ON d.id = t.department_id
WHERE t.rnk = 1;Pièges à éviter
Erreurs courantes dans le classement par groupe :
- Oublier
PARTITION BYet classer globalement, ce qui ne renvoie que l'employé le mieux rémunéré de toute l'entreprise. - Utiliser
ROW_NUMBERlorsque la question laisse entendre que toutes les égalités doivent apparaître, ce qui élimine silencieusement les employés ex aequo en tête. - Essayer de placer la fonction de fenêtre directement dans
WHEREau lieu de l'englober. - Joindre la table des départements avant le classement et modifier accidentellement la granularité du partitionnement.
Vérification rapide
Choisissez la fonction de classement adaptée à l'exigence.
Récapitulatif
Le salarié le mieux rémunéré par département repose sur le schéma de classement global auquel on ajoute PARTITION BY department_id :
- DENSE_RANK = 1 renvoie tous les salariés les mieux rémunérés à égalité dans chaque département.
- ROW_NUMBER = 1 avec un critère de départage renvoie exactement un salarié par département.
- Autres solutions portables : un
MAXcorrélé par département, ou le maximum obtenu avecGROUP BYpuis joint au reste de la table.
Pour obtenir les N premiers, remplacez = 1 par <= N. Indiquez clairement la façon dont vous gérez les égalités.
Questions Fréquemment Posées
La leçon « Le plus gros salaire par service » est-elle gratuite ?
Oui — le texte complet de « Le plus gros salaire par service » 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 « Le plus gros salaire par service » ?
Combiner partitionnement et classement pour résoudre les problèmes de salaire maximal par groupe 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 « Le plus gros salaire par service » ?
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
- Deuxième salaire le plus élevé : cinq méthodes
- N-ième valeur la plus élevée avec DENSE_RANK
- Le plus gros salaire par service
- Renvoyer NULL lorsqu’il n’existe aucune n-ième valeur