Quiero hacer una consulta que muestre una tabla con los meses en columnas
y la cantidad de veces que ha faltado una persona por cada mes, sería algo como esto:
Nombre | Enero | Febrero | Marzo | Abril | ....
Persona1 | 12 | 21 | 32 | 26 | .....
Persona2 | 12 | 21 | 32 | 26 | .....
Hola,
MySQL no tiene un operador PIVOT nativo (a diferencia de SQL Server o de Oracle en sus versiones más recientes), así que la forma habitual de conseguir columnas por mes es con agregación condicional: un SUM(CASE ...) distinto por cada columna que quieras generar.
Suponiendo que tienes una tabla faltas con una fila por cada falta registrada (columnas nombre y fecha_falta):
SELECT
nombre,
SUM(CASE WHEN MONTH(fecha_falta) = 1 THEN 1 ELSE 0 END) AS Enero,
SUM(CASE WHEN MONTH(fecha_falta) = 2 THEN 1 ELSE 0 END) AS Febrero,
SUM(CASE WHEN MONTH(fecha_falta) = 3 THEN 1 ELSE 0 END) AS Marzo,
SUM(CASE WHEN MONTH(fecha_falta) = 4 THEN 1 ELSE 0 END) AS Abril,
SUM(CASE WHEN MONTH(fecha_falta) = 5 THEN 1 ELSE 0 END) AS Mayo,
SUM(CASE WHEN MONTH(fecha_falta) = 6 THEN 1 ELSE 0 END) AS Junio,
SUM(CASE WHEN MONTH(fecha_falta) = 7 THEN 1 ELSE 0 END) AS Julio,
SUM(CASE WHEN MONTH(fecha_falta) = 8 THEN 1 ELSE 0 END) AS Agosto,
SUM(CASE WHEN MONTH(fecha_falta) = 9 THEN 1 ELSE 0 END) AS Septiembre,
SUM(CASE WHEN MONTH(fecha_falta) = 10 THEN 1 ELSE 0 END) AS Octubre,
SUM(CASE WHEN MONTH(fecha_falta) = 11 THEN 1 ELSE 0 END) AS Noviembre,
SUM(CASE WHEN MONTH(fecha_falta) = 12 THEN 1 ELSE 0 END) AS Diciembre
FROM faltas
GROUP BY nombre;
La lógica de cada columna es la misma: por cada fila de la tabla, el CASE devuelve 1 si esa falta ocurrió en el mes que toca esa columna, y 0 si no. El SUM agrupado por nombre (gracias al GROUP BY) suma esos unos y ceros, así que el resultado final es, para cada persona, cuántas faltas tuvo en cada mes concreto.
Si además necesitas que solo cuente faltas de un año en concreto (para no mezclar 2024 con 2025), añade un WHERE YEAR(fecha_falta) = 2026 antes del GROUP BY.
Un saludo,
David Carrero