Reto: un reporte mensual que no se rompe
Arma el reporte mensual por sucursal con todo lo del curso, y vuelve a las preguntas del principio.
Curso gratis. Tu Maestro, una IA, .
El reporte que pide la dirección
La dirección de Café Altura quiere una tabla para su junta anual: las ventas de cada sucursal en cada mes de 2025. Las tres sucursales, los doce meses, aunque una sucursal no haya abierto un mes. Son 36 filas, y la de Coyoacán en agosto dice 0.
Antes de escribir la consulta, repasa la lista de lo que puede romper un reporte con fechas. No todo aplica a cada reporte; revisarlo es lo que hace que no se rompa.
Revisa el tipo y el formato
Si la fecha es texto, conviértela con un formato explícito decidido con los datos, no con una fila.
Pasa la hora a la zona del negocio
Si viene en UTC, conviértela con el nombre de la zona, como
America/Mexico_City, antes de sacar días o meses.Filtra con intervalos semiabiertos
Desde el primer instante del periodo hasta antes del primero del siguiente:
>= '2025-01-01' AND < '2026-01-01'.Agrupa por un periodo con año
Trunca al mes, al trimestre o al lunes de la semana. Nunca por el número del mes solo.
Une un calendario
Para que aparezca cada periodo, haya filas o no, y decide qué valor lleva un periodo vacío.
Compara tramos iguales
El mismo tramo del calendario con cobertura equivalente, completo o parcial, y dilo en el reporte.
Inténtalo
La consulta de abajo ya tiene un calendario de los meses de 2025 (meses) y las ventas por sucursal y mes (por_mes), pero devuelve 35 filas: falta Coyoacán en agosto. Te faltan dos pasos. Primero, un calendario de sucursal por mes: toma las sucursales distintas y combínalas con cada mes con CROSS JOIN, que junta cada fila de una tabla con cada fila de la otra. Después, pega por_mes a ese calendario con un LEFT JOIN por sucursal y mes, y pon 0 donde no haya ventas.
Una buena respuesta tiene 36 filas ordenadas por sucursal y mes, y la fila de Coyoacán del 2025-08-01 en 0. Si te atoras en el CROSS JOIN, pregúntale a tu Maestro.
Tu turno
Arma el reporte de ventas por sucursal y mes de 2025, con las 3 sucursales y los 12 meses (36 filas) y 0 donde no hubo ventas, ordenado por sucursal y mes.
Tablas: ventas_diarias (fecha, sucursal, ventas)
ventas_diarias · 1,598 filas
| Columna | Tipo |
|---|---|
| fecha El día de la venta. | DATE |
| sucursal Roma, Coyoacán o Del Valle. | VARCHAR |
| ventas Ventas del día en pesos. | BIGINT |
Primeras filas
| fecha | sucursal | ventas |
|---|---|---|
| 2025-01-02 | Roma | 12120 |
| 2025-01-02 | Coyoacán | 10650 |
| 2025-01-02 | Del Valle | 8880 |
Tab agrega sangría; Esc y Tab para salir
O en pandas
Si prefieres pandas, arma el mismo reporte: agrupa por sucursal y mes, haz un calendario con pd.MultiIndex.from_product (cada sucursal con cada mes) y pégalo con reindex(..., fill_value=0). Una buena respuesta imprime 36 filas y la de Coyoacán en agosto en 0.
Tu turno
Arma en pandas el reporte de ventas por sucursal y mes de 2025, con las 3 sucursales y los 12 meses y 0 donde no hubo ventas. Imprime cuántas filas tiene y las filas en 0.
Datos: ventas-diarias, 1,598 filas
| Fila | Quitar | |||
|---|---|---|---|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 | ||||
| 8 | ||||
| 9 | ||||
| 10 | ||||
| 11 | ||||
| 12 | ||||
| 13 | ||||
| 14 | ||||
| 15 | ||||
| 16 | ||||
| 17 | ||||
| 18 | ||||
| 19 | ||||
| 20 |
Enter guarda; Esc deshace; vacía es un valor faltante
Tab agrega sangría; Esc y Tab para salir
Las preguntas del principio
Al empezar contestaste seis preguntas. Aquí van seis parecidas, con otros datos. Compara lo que contestas ahora con lo que contestaste entonces.
Comprueba lo que sabes, 1 de 6: Una columna de texto en formato día/mes/año tiene 10/02/2026, 03/03/2026 y 25/01/2026. Con ORDER BY fecha, ¿cuál sale al final?
Comprueba lo que sabes, 2 de 6: En tu archivo, 11/12/2026 es el 11 de diciembre. Si lo conviertes con pd.to_datetime sin formato, ¿qué fecha queda?
Comprueba lo que sabes, 3 de 6: La columna creado tiene fecha y hora. ¿Qué filtro cuenta todos los pedidos de la semana del lunes 9 al domingo 15 de marzo de 2026?
Comprueba lo que sabes, 4 de 6: Un sistema en UTC guarda un pedido como 2026-04-01 05:15:00. Para una tienda de Ciudad de México, ¿en qué mes cuenta ese pedido?
Comprueba lo que sabes, 5 de 6: Una tienda en línea no tuvo pedidos el 1 de mayo. Cuentas los pedidos por día con GROUP BY. ¿Qué pasa con el 1 de mayo?
Comprueba lo que sabes, 6 de 6: Luis nació el 3 de noviembre de 1984. ¿Qué edad tiene el 30 de junio de 2026?
Lo que ya puedes hacer
Con pandas y con DuckDB, ahora puedes:
- Saber si una columna de fechas es texto y por qué eso cambia un orden, un filtro o un máximo.
- Decidir con los datos si un archivo trae el día o el mes primero, y convertirlo con un formato explícito.
- Guardar y compartir fechas en ISO 8601.
- Filtrar fechas con hora sin perder el último día, con intervalos semiabiertos.
- Pasar de UTC a la hora de Ciudad de México con el nombre de la zona.
- Agrupar por mes, trimestre y semana ISO sin juntar años.
- Hacer que aparezcan los periodos sin datos y decidir qué valor llevan.
- Calcular días, meses completos y edades, y comparar contra el mismo periodo del año pasado.
Lo que sigue
En este curso usaste WITH, LEFT JOIN y GROUP BY como herramientas. Si quieres dominarlas desde la base, o te costaron en los ejercicios, el curso SQL para gente de datos: piensa en tablas, no en hojas de cálculo enseña SQL desde cero en DuckDB: filtros, agrupaciones, joins, CTE y CASE WHEN. Si no sabes si te conviene, cuéntale a tu Maestro qué haces con datos.
Piensa en un reporte con fechas que haces o lees en tu trabajo. ¿Cuál de los pasos de la lista de esta página le falta, y qué cambiaría en sus números si lo agregas?
Reflexiona: Piensa en un reporte con fechas que haces o lees en tu trabajo. ¿Cuál de los pasos de la lista de esta página le falta, y qué cambiaría en sus números si lo agregas?
Solo tú y tu Maestro leen esto. Se queda en tu cuenta y se borra con ella.