Skip to content

¿Cómo saco el top 3 de cada grupo en SQL, con empates?

El reto final: saca los 3 productos más vendidos de cada mes, empates incluidos, con las cuatro decisiones del curso, y mide qué tanto cambió lo que sabes.

Curso gratis. Tu Maestro, una IA, .

Este es el reto final del curso. La tabla ventas_productos tiene las unidades vendidas de seis productos de una fonda, de enero a abril de 2025. La pregunta del negocio: ¿cuáles fueron los 3 productos más vendidos de cada mes? Y si dos empatan en el tercer lugar, los dos se mencionan.

Todos los problemas de este curso se resolvieron con las mismas cuatro decisiones, en este orden. Tómalas antes de escribir una sola línea:

  1. La partición

    ¿Dentro de qué grupo se compara cada fila? Eso va en PARTITION BY. Si la pregunta dice "de cada", ahí está tu partición.

  2. El orden

    ¿Qué hace que una fila vaya antes que otra, y en qué dirección? Eso va en el ORDER BY de adentro. Si puede haber empates, decide si necesitas un desempate.

  3. La función

    ¿Qué le pasa a un empate? ROW_NUMBER lo rompe, RANK lo comparte y deja hueco, DENSE_RANK lo comparte sin hueco.

  4. El filtro

    ¿Dónde cortas? Nunca en WHERE: en QUALIFY, o en el WHERE de afuera de un WITH. Y nunca con LIMIT, que corta el resultado entero.

Primero, mira las cuatro decisiones tomadas con datos que ya conoces. Abre los pasos uno por uno, y antes de abrir cada uno, intenta decir tú qué sigue. Si tu primera idea para el reto es GROUP BY mes con MAX(unidades), fíjate en lo que te daría: un solo número por mes, sin el nombre del producto y sin el segundo ni el tercer lugar. Para eso sirve una ventana: rankea sin juntar filas.

Los 2 mejores meses de cada sucursal

Ejemplo resuelto · 4 pasos

Con ventas_mensuales: para cada sucursal, sus 2 meses de 2025 con más ventas, con mes, ventas y su lugar.

Piensa el siguiente paso por tu cuenta y luego ábrelo para comparar.

Inténtalo

Contesta la pregunta de abajo y escribe tu consulta. Si te atoras en una de las cuatro decisiones, cuéntale a tu Maestro cuál.

Comprueba lo que sabes: En febrero, Café de olla y Concha vendieron 134 unidades cada uno, empatados en el tercer lugar. Si usas ROW_NUMBER() OVER (PARTITION BY mes ORDER BY unidades DESC, producto) y QUALIFY ... <= 3, ¿qué pasa en febrero?

Regresa mes, producto, unidades y lugar (el lugar del producto en su mes, de más a menos unidades) solo para los productos en los lugares 1 a 3 de cada mes. Si hay empate, los empatados comparten lugar y entran todos. Ordena por mes, lugar, producto. Terminaste cuando ves 3 produ

Tu turno

Regresa mes, producto, unidades y lugar (el lugar del producto en su mes, de más a menos unidades) solo para los productos en los lugares 1 a 3 de cada mes. Si hay empate, los empatados comparten lugar y entran todos. Ordena por mes, lugar, producto. Terminaste cuando ves 3 productos por mes, salvo uno con un empate.

Tablas: ventas_productos (mes, producto, unidades)

ventas_productos · 24 filas

ColumnaTipo
mes Primer día del mes.DATE
producto Nombre del producto.VARCHAR
unidades Unidades vendidas en el mes.BIGINT

Primeras filas

mesproductounidades
2025-01-01Café de olla56
2025-01-01Concha128
2025-01-01Tamal149

Cada ejecución empieza con copias nuevas de las tablas del curso, así que puedes probar lo que quieras.

Listo para ejecutar tu consulta.

Ejecútalo tú

Si elegiste RANK, febrero tiene 4 productos: Café de olla y Concha vendieron 134 unidades cada uno y comparten el tercer lugar. Así se ve febrero con las tres funciones, en una corrida en el sandbox (ROW_NUMBER desempatado por producto):

productounidadesROW_NUMBERRANKDENSE_RANK
Chilaquiles155111
Pan de elote151222
Café de olla134333
Concha134433
Atole98554
Tamal46665

Con ROW_NUMBER hubieras dejado fuera a Concha sin ninguna razón que tú hayas elegido. Aquí DENSE_RANK con <= 3 da el mismo resultado que RANK, porque el empate está justo en el corte. Pero si hubiera un empate más arriba, "lugar 3" con DENSE_RANK abarcaría más productos de los que pediste: con RANK, en cambio, un empate en el primer lugar se come el segundo.

Es de las preguntas de entrevista más comunes: "los 3 productos más vendidos de cada categoría", "los 2 empleados mejor pagados de cada departamento" o "el top 5 de canciones por país". Antes de escribir, pregunta qué pasa con un empate: esa pregunta, dicha en voz alta, ya es la mitad de la respuesta que buscan. Si quieres ensayarla, pídele a tu Maestro que te haga una versión con otros datos.

Tu tarea para esta semana: busca un reporte que diga "top" o "los principales" y revisa cómo corta. Si usa LIMIT sobre un resultado con varios grupos, o ROW_NUMBER sin que nadie haya decidido qué pasa con un empate, ya sabes qué preguntar.

¿Qué tanto cambió lo que sabes?

En la primera página contestaste cinco preguntas antes de empezar. Aquí están otra vez, con otras palabras y otros datos.

Comprueba lo que sabes: Una tabla tiene 24 filas de 4 meses. Agregas AVG(unidades) OVER (PARTITION BY mes) al SELECT, sin GROUP BY. ¿Cuántas filas regresa?

Comprueba lo que sabes: Calculaste lugar con RANK() OVER (PARTITION BY mes ORDER BY unidades DESC) AS lugar. ¿Dónde puedes escribir la condición lugar <= 3?

Comprueba lo que sabes: Tres productos venden 120, 120 y 95 unidades. ¿Qué lugar le da DENSE_RANK al de 95?

Comprueba lo que sabes: Haces un acumulado con SUM(unidades) OVER (ORDER BY mes) y hay seis filas por mes. ¿Qué muestran las seis filas de enero?

Comprueba lo que sabes: Un cliente compró en enero, febrero y abril, pero no en marzo. Con LAG(fecha) OVER (ORDER BY fecha), ¿qué sale en la fila de abril?

Piensa en una consulta o un reporte de tu trabajo. ¿Dónde usarías primero una de estas ventanas, y qué trampa de este curso (empates, un mes que falta, el marco por omisión o el WHERE antes de la ventana) tendrías que revisar antes de confiar en el resultado?

Reflexiona: Piensa en una consulta o un reporte de tu trabajo. ¿Dónde usarías primero una de estas ventanas, y qué trampa de este curso (empates, un mes que falta, el marco por omisión o el WHERE antes de la ventana) tendrías que revisar antes de confiar en el resultado?

Solo tú y tu Maestro leen esto. Se queda en tu cuenta y se borra con ella.

Lo que sigue

Ya puedes poner el total de un grupo junto a cada fila, numerar y quedarte con una fila por grupo, comparar con la fila anterior sabiendo que LAG cuenta filas y no meses, acumular y suavizar eligiendo tu marco, y decir en qué momento corre cada pieza. Con eso resuelves la mayoría de las consultas con ventanas que vas a ver en reportes y en entrevistas.

El mejor siguiente paso es llevar una de estas consultas a tus datos del trabajo, con tu Maestro al lado. Este curso no enseña uniones ni cómo crear datos: si en el camino sentiste flojo GROUP BY, las uniones o los WITH, el curso SQL para gente de datos los trabaja a fondo, desde qué es una base de datos.

Aquí termina la lectura; tu Maestro sigue.