MONTH

La función MONTH extrae el número de mes de una fecha y lo devuelve como un entero entre 1 y 12. Enero es 1, febrero es 2 y así sucesivamente hasta diciembre que es 12. Es una de las funciones de fecha más utilizadas en MySQL porque los informes mensuales son la base de prácticamente cualquier análisis empresarial.

Mientras que YEAR te da la visión macro del negocio, MONTH te permite ver los patrones estacionales: qué meses venden más, cuándo bajan las contrataciones, en qué época del año los clientes compran cierto tipo de producto. Todo ese análisis empieza extrayendo el mes de una fecha.

Sintaxis

MONTH(fecha)

El argumento fecha acepta valores de tipo DATE, DATETIME, TIMESTAMP o una cadena con formato de fecha válido. Devuelve un entero de 1 a 12. Si la fecha es '0000-00-00', devuelve 0.

Comportamiento básico

MONTH toma cualquier fecha y devuelve su componente de mes como un número simple:

SELECT
    MONTH('2025-01-15') AS enero,
    MONTH('2025-06-20') AS junio,
    MONTH('2025-12-31') AS diciembre,
    MONTH(NOW()) AS mes_actual;
enerojuniodiciembremes_actual
16122

El resultado es siempre un entero sin ceros a la izquierda. Enero es 1, no "01". Si necesitas el nombre del mes en lugar del número, MySQL ofrece la función MONTHNAME() que devuelve el nombre en el idioma configurado.

Aplicar MONTH a una columna

El uso típico es extraer el mes de una columna de fecha en tus consultas:

SELECT
    nombre,
    fecha_pedido,
    MONTH(fecha_pedido) AS mes_pedido
FROM pedidos
ORDER BY fecha_pedido
LIMIT 5;
nombrefecha_pedidomes_pedido
Pedido #40102024-01-031
Pedido #40112024-01-051
Pedido #40122024-01-071
Pedido #40132024-02-012
Pedido #40142024-02-042

Caso práctico: informe mensual de ventas

El escenario más común para MONTH es generar informes mensuales. Agrupando por mes puedes ver cómo evolucionan las ventas a lo largo del año:

SELECT
    MONTH(fecha_venta) AS mes,
    COUNT(*) AS num_ventas,
    SUM(total) AS ingresos,
    ROUND(AVG(total), 2) AS ticket_medio
FROM ventas
WHERE YEAR(fecha_venta) = 2024
GROUP BY MONTH(fecha_venta)
ORDER BY mes;
mesnum_ventasingresosticket_medio
138057000.00150.00
234551750.00150.00
341065600.00160.00
442572250.00170.00
539867660.00170.00
644079200.00180.00
737062900.00170.00
835560350.00170.00
941570550.00170.00
1045081000.00180.00
1147886040.00180.00
1252098800.00190.00

De esta tabla puedes detectar que las ventas suben considerablemente en el último trimestre (octubre a diciembre), probablemente por las campañas de fin de año. Julio y agosto muestran un bajón típico del periodo vacacional.

Caso práctico: análisis estacional con agrupación por año y mes

Cuando necesitas comparar el mismo mes entre distintos años, combina YEAR y MONTH en el GROUP BY:

SELECT
    YEAR(fecha_venta) AS anio,
    MONTH(fecha_venta) AS mes,
    SUM(total) AS ingresos
FROM ventas
WHERE MONTH(fecha_venta) IN (11, 12)
    AND YEAR(fecha_venta) >= 2022
GROUP BY YEAR(fecha_venta), MONTH(fecha_venta)
ORDER BY anio, mes;
aniomesingresos
20221168500.00
20221282300.00
20231176200.00
20231291500.00
20241186040.00
20241298800.00

Este análisis revela que noviembre y diciembre crecen consistentemente año tras año. El filtro MONTH(fecha_venta) IN (11, 12) selecciona solo esos dos meses, y al agrupar también por YEAR puedes ver la tendencia histórica.

Caso práctico: categorizar meses por temporada

Puedes usar MONTH dentro de una expresión CASE para agrupar meses en categorías de negocio como temporadas:

SELECT
    CASE
        WHEN MONTH(fecha_venta) IN (12, 1, 2) THEN 'Invierno'
        WHEN MONTH(fecha_venta) IN (3, 4, 5) THEN 'Primavera'
        WHEN MONTH(fecha_venta) IN (6, 7, 8) THEN 'Verano'
        WHEN MONTH(fecha_venta) IN (9, 10, 11) THEN 'Otoño'
    END AS temporada,
    COUNT(*) AS num_ventas,
    SUM(total) AS ingresos,
    ROUND(AVG(total), 2) AS ticket_medio
FROM ventas
WHERE YEAR(fecha_venta) = 2024
GROUP BY
    CASE
        WHEN MONTH(fecha_venta) IN (12, 1, 2) THEN 'Invierno'
        WHEN MONTH(fecha_venta) IN (3, 4, 5) THEN 'Primavera'
        WHEN MONTH(fecha_venta) IN (6, 7, 8) THEN 'Verano'
        WHEN MONTH(fecha_venta) IN (9, 10, 11) THEN 'Otoño'
    END
ORDER BY ingresos DESC;
temporadanum_ventasingresosticket_medio
Otoño1343237590.00176.91
Invierno1245207550.00166.67
Primavera1233205510.00166.68
Verano1165202450.00173.78

Este enfoque es más informativo que mostrar 12 filas individuales cuando lo que importa es la tendencia estacional. El CASE convierte los números de mes en etiquetas comprensibles que cualquier persona de negocio puede interpretar sin pensar qué mes es el 3 o el 9.

Caso práctico: tabla pivotada mes a mes

Un patrón avanzado pero muy útil es pivotar los datos mensuales en columnas usando MONTH dentro de expresiones CASE:

SELECT
    categoria,
    SUM(CASE WHEN MONTH(fecha_venta) = 1 THEN total ELSE 0 END) AS ene,
    SUM(CASE WHEN MONTH(fecha_venta) = 2 THEN total ELSE 0 END) AS feb,
    SUM(CASE WHEN MONTH(fecha_venta) = 3 THEN total ELSE 0 END) AS mar,
    SUM(CASE WHEN MONTH(fecha_venta) = 4 THEN total ELSE 0 END) AS abr,
    SUM(CASE WHEN MONTH(fecha_venta) = 5 THEN total ELSE 0 END) AS may,
    SUM(CASE WHEN MONTH(fecha_venta) = 6 THEN total ELSE 0 END) AS jun
FROM ventas
    JOIN productos USING (id_producto)
WHERE YEAR(fecha_venta) = 2024
GROUP BY categoria;
categoriaenefebmarabrmayjun
Electrónica18500.0016200.0021300.0023400.0019800.0025100.00
Ropa12300.0011500.0014800.0016200.0015600.0018700.00
Alimentación26200.0024050.0029500.0032650.0032260.0035400.00

Esta tabla cruzada es el formato que suelen pedir los informes de gestión. Cada fila es una categoría y cada columna un mes, lo que facilita la comparación visual.

MONTH con NULL

MONTH devuelve NULL cuando la entrada es NULL:

SELECT
    MONTH(NULL) AS resultado,
    MONTH('0000-00-00') AS fecha_cero;
resultadofecha_cero
NULL0

Al igual que YEAR, una fecha '0000-00-00' devuelve 0 en lugar de NULL. Si tu tabla puede contener este tipo de valores, filtra con WHERE fecha IS NOT NULL AND fecha != '0000-00-00' para evitar resultados inesperados en tus agrupaciones.

Combinación con otras funciones

MONTH se combina especialmente bien con MONTHNAME para añadir etiquetas legibles y con LPAD para formatear el número con cero a la izquierda:

SELECT
    MONTH(fecha_venta) AS num_mes,
    MONTHNAME(fecha_venta) AS nombre_mes,
    LPAD(MONTH(fecha_venta), 2, '0') AS mes_formateado,
    CONCAT(YEAR(fecha_venta), '-', LPAD(MONTH(fecha_venta), 2, '0')) AS periodo,
    COUNT(*) AS ventas
FROM ventas
WHERE YEAR(fecha_venta) = 2024
GROUP BY
    MONTH(fecha_venta),
    MONTHNAME(fecha_venta),
    YEAR(fecha_venta)
ORDER BY num_mes
LIMIT 4;
num_mesnombre_mesmes_formateadoperiodoventas
1January012024-01380
2February022024-02345
3March032024-03410
4April042024-04425

Nota que MONTHNAME devuelve el nombre en inglés por defecto. Si quieres que aparezca en español, necesitas configurar la variable lc_time_names con SET lc_time_names = 'es_ES' antes de ejecutar la consulta.

En el siguiente artículo veremos DAY para extraer el día del mes.

Escrito por Eduardo Lázaro