La persona con mayores ingresos por departamento
Combine particionamiento y clasificación para resolver problemas de salarios superiores por grupo
La persona con mayores ingresos por departamento es una lección gratuita de SQL Interview Prep en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Interview Prep, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Interview Prep incluye 4 lecciones en total.
De la clasificación global a la clasificación por grupo
El siguiente nivel de dificultad es: «Encuentre al empleado con el salario más alto de cada departamento». Esto combina la clasificación con la agrupación y es una pregunta de nivel intermedio muy habitual.
Suponga una tabla employee con id, name, department_id y salary. Queremos obtener al empleado con el salario más alto de cada departamento (o a varios si hay empate), no solo el máximo global.
La nueva herramienta clave es PARTITION BY, que reinicia la clasificación dentro de cada departamento.
CREATE TABLE employee (
id INT PRIMARY KEY,
name VARCHAR(100),
department_id INT,
salary INT
);PARTITION BY reinicia la clasificación
Al añadir PARTITION BY department_id a la ventana, indicamos a la base de datos que calcule la clasificación de forma independiente dentro de cada departamento.
Cada departamento comienza su propio rango 1. Por tanto, el empleado con el salario más alto del departamento 1 y el del departamento 5 reciben ambos el rango 1. Sin particionar, solo el máximo global recibiría el rango 1.
SELECT name, department_id, salary,
DENSE_RANK() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS rnk
FROM employee;Filtrar por el rango 1
Para conservar únicamente a los empleados con los salarios más altos, envuelva la consulta clasificada y filtre por el rango 1. Como siempre, la función de ventana debe calcularse en una subconsulta o CTE antes de poder filtrarla.
Usar DENSE_RANK (o RANK) aquí significa que, si dos empleados empatan con el salario más alto de un departamento, se devuelven ambos. Esa suele ser la interpretación correcta de «el empleado con el salario más alto».
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 cuando necesita exactamente uno
A veces, el entrevistador quiere exactamente una fila por departamento, incluso si hay empate. En ese caso, use ROW_NUMBER y añada un criterio de desempate determinista, como el id más bajo.
Sin ese criterio, los empates se resuelven arbitrariamente y el resultado no es determinista. Añadir , id ASC hace que la elección sea repetible.
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 frente a ROW_NUMBER y RANK en este caso
Elija según el enunciado exacto:
- DENSE_RANK = 1: todos los empleados empatados con el salario más alto de cada departamento.
- RANK = 1: es idéntico a DENSE_RANK para el primer puesto; las diferencias solo importan por debajo del rango 1.
- ROW_NUMBER = 1: exactamente un empleado por departamento, con los empates resueltos mediante su ORDER BY.
Lo que se evalúa en la entrevista es indicar cuál eligió y por qué.
El enfoque correlacionado anterior a las funciones de ventana
Antes de que existieran las funciones de ventana, la solución estándar era una subconsulta correlacionada: conservar una fila solo si nadie del mismo departamento gana más.
Esto devuelve naturalmente a todos los empleados empatados en el primer puesto. Es portable, pero puede ser lento porque el MAX interno se evalúa para cada fila externa, salvo que el optimizador lo reescriba.
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
);El enfoque de unión con GROUP BY
Otro patrón portable: calcular el salario máximo por departamento con GROUP BY y después volver a unirlo para obtener los empleados correspondientes.
Es eficiente y claro. La unión recupera a todos los empleados cuyo salario es igual al máximo de su departamento, por lo que conserva los empates.
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;Los N primeros por departamento
El patrón se extiende a «los 3 empleados con mayores ingresos por departamento» sin ninguna idea nueva. Solo tiene que cambiar el filtro por un intervalo.
Con DENSE_RANK, rnk <= 3 devuelve los tres niveles salariales distintos más altos, posiblemente más de tres filas si hay empates. Con ROW_NUMBER, rn <= 3 devuelve exactamente tres filas por departamento.
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;Ejemplo resuelto
Departamento 1: Ana 120, Bob 120, Cara 90. Departamento 2: Dan 200, Eve 150.
- DENSE_RANK = 1: Ana (120) y Bob (120) del departamento 1; Dan (200) del departamento 2. Tres filas.
- ROW_NUMBER = 1 con un criterio de desempate basado en id: uno de Ana/Bob, el que tenga el id más bajo, y Dan. Dos filas.
Los mismos datos producen distintos números de filas según la función. Elija la opción que corresponda a la pregunta.
Incluir departamentos y unir sus nombres
Los entrevistadores suelen añadir una tabla department y pedir el nombre del departamento. Solo tiene que unirla después de asignar los rangos.
Mantenga la clasificación en la tabla employee y una la tabla de consulta al final, para que la partición siga realizándose con la granularidad adecuada.
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;Errores que debe evitar
Errores comunes al clasificar por grupo:
- Olvidar
PARTITION BYy clasificar globalmente, devolviendo solo al empleado con el salario más alto de toda la empresa. - Usar
ROW_NUMBERcuando la pregunta implica que deben aparecer todos los empates, eliminando silenciosamente a los empleados empatados en el primer puesto. - Intentar colocar la función de ventana directamente en
WHEREen lugar de envolverla. - Unir la tabla de departamentos antes de clasificar y cambiar accidentalmente la granularidad de la partición.
Comprobación rápida
Elija la función de clasificación adecuada para el requisito.
Resumen
Obtener el empleado con el salario más alto por departamento consiste en aplicar el patrón de clasificación global junto con PARTITION BY department_id:
- DENSE_RANK = 1 devuelve todos los empleados empatados en el primer puesto de cada departamento.
- ROW_NUMBER = 1 con un criterio de desempate devuelve exactamente uno por departamento.
- Alternativas portables: un
MAXcorrelacionado por departamento o el máximo obtenido conGROUP BYy vuelto a unir a la tabla.
Para obtener los N primeros, cambie = 1 por <= N. Explique en voz alta cómo ha decidido gestionar los empates.
Preguntas frecuentes
¿La lección «La persona con mayores ingresos por departamento» es gratis?
Sí — el texto completo de «La persona con mayores ingresos por departamento» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Interview Prep, actualiza a CoddyKit PRO. El curso de SQL Interview Prep incluye 4 lecciones en total.
¿Qué aprenderé en «La persona con mayores ingresos por departamento»?
Combine particionamiento y clasificación para resolver problemas de salarios superiores por grupo Practicas SQL Interview Prep con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar SQL Interview Prep?
No se requiere experiencia previa. SQL Interview Prep en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «La persona con mayores ingresos por departamento»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de SQL Interview Prep?
Sí. Cada lección de SQL Interview Prep incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- El segundo salario más alto, de cinco formas
- El enésimo valor más alto con DENSE_RANK
- La persona con mayores ingresos por departamento
- Devolver NULL cuando no existe el enésimo valor