YEAR

La función YEAR extrae el componente de año de una fecha y lo devuelve como un número entero. Es la forma más directa y legible de obtener el año de un valor DATE, DATETIME o TIMESTAMP en MySQL. Aunque podrías usar EXTRACT(YEAR FROM fecha) para lograr lo mismo, YEAR() es más concisa y se ha convertido en la opción preferida en la mayoría de proyectos MySQL.

YEAR es una de las funciones de fecha que más usarás en la práctica. Filtrar registros por año, agrupar ventas anuales, comparar rendimiento entre años: todos estos escenarios aparecen constantemente en aplicaciones reales.

Sintaxis

YEAR(fecha)

El argumento fecha puede ser un valor de tipo DATE, DATETIME, TIMESTAMP o una cadena con formato de fecha válido. La función devuelve un entero entre 1000 y 9999, que corresponde al rango de años que MySQL puede almacenar. Si el valor de entrada es '0000-00-00', la función devuelve 0.

Comportamiento básico

En su forma más simple, YEAR toma una fecha y devuelve el año como número:

SELECT
    YEAR('2025-08-15') AS desde_date,
    YEAR('2025-08-15 14:30:00') AS desde_datetime,
    YEAR(NOW()) AS anio_actual;
desde_datedesde_datetimeanio_actual
202520252025

No importa si le pasas un DATE o un DATETIME: YEAR ignora la parte de tiempo y devuelve únicamente el año. El resultado siempre es un entero, sin ceros a la izquierda ni formato especial.

Usar YEAR con columnas de tabla

El uso más habitual es aplicar YEAR sobre una columna de fecha en tus consultas:

SELECT
    nombre,
    fecha_contratacion,
    YEAR(fecha_contratacion) AS anio_contratacion
FROM empleados
LIMIT 5;
nombrefecha_contratacionanio_contratacion
María García2019-03-152019
Carlos López2020-07-222020
Ana Rodríguez2021-01-102021
Pedro Martínez2022-11-052022
Laura Sánchez2023-06-182023

Caso práctico: filtrar registros por año

Una de las aplicaciones más comunes de YEAR es filtrar registros de un año específico en la cláusula WHERE. Esto es más legible que usar rangos de fechas:

SELECT
    id_venta,
    fecha_venta,
    cliente,
    total
FROM ventas
WHERE YEAR(fecha_venta) = 2024
ORDER BY fecha_venta
LIMIT 5;
id_ventafecha_ventaclientetotal
32012024-01-02Importaciones del Sur4500.00
32022024-01-03Distribuciones Norte2300.00
32032024-01-03Comercial Mediterráneo1875.50
32042024-01-04Logística Central6200.00
32052024-01-05Mayoristas Unidos3150.75

Sin embargo, hay un detalle de rendimiento importante: YEAR(fecha_venta) = 2024 no puede aprovechar un índice en la columna fecha_venta porque MySQL necesita aplicar la función a cada fila antes de comparar. Si tienes millones de registros, es más eficiente usar un rango:

-- Más eficiente con índices
SELECT id_venta, fecha_venta, cliente, total
FROM ventas
WHERE fecha_venta >= '2024-01-01'
  AND fecha_venta < '2025-01-01';

Ambas consultas devuelven los mismos resultados, pero la segunda puede usar un índice en fecha_venta. Usa YEAR() en WHERE cuando la tabla es pequeña o cuando la legibilidad es más importante que el rendimiento. Para tablas grandes, prefiere rangos.

Caso práctico: agrupar ventas por año

El escenario clásico de YEAR en combinación con GROUP BY: obtener un resumen anual de ventas.

SELECT
    YEAR(fecha_venta) AS anio,
    COUNT(*) AS num_ventas,
    SUM(total) AS ingresos_totales,
    ROUND(AVG(total), 2) AS ticket_medio,
    MIN(total) AS venta_minima,
    MAX(total) AS venta_maxima
FROM ventas
WHERE fecha_venta >= '2021-01-01'
GROUP BY YEAR(fecha_venta)
ORDER BY anio;
anionum_ventasingresos_totalesticket_medioventa_minimaventa_maxima
20213420513000.00150.0012.508500.00
20223890622400.00160.0415.009200.00
20234250722500.00170.0018.7511500.00
20244810865800.00180.0022.0012800.00

Este tipo de consulta es el pan de cada día en cualquier dashboard empresarial. De un vistazo puedes ver la evolución del negocio: más ventas cada año, ticket medio creciente y ventas máximas más altas.

Caso práctico: comparar año actual vs anterior

Un patrón muy útil es comparar las cifras del año en curso con las del año anterior para medir el crecimiento:

SELECT
    YEAR(fecha_venta) AS anio,
    SUM(total) AS ingresos,
    LAG(SUM(total)) OVER (ORDER BY YEAR(fecha_venta)) AS ingresos_anterior,
    ROUND(
        (SUM(total) - LAG(SUM(total)) OVER (ORDER BY YEAR(fecha_venta)))
        / LAG(SUM(total)) OVER (ORDER BY YEAR(fecha_venta)) * 100,
    1) AS crecimiento_pct
FROM ventas
WHERE YEAR(fecha_venta) >= 2021
GROUP BY YEAR(fecha_venta)
ORDER BY anio;
anioingresosingresos_anteriorcrecimiento_pct
2021513000.00NULLNULL
2022622400.00513000.0021.3
2023722500.00622400.0016.1
2024865800.00722500.0019.8

La función ventana LAG combinada con YEAR te permite calcular el porcentaje de crecimiento interanual directamente en SQL, sin necesidad de procesar los datos en tu aplicación.

Caso práctico: rangos de años con BETWEEN

A veces necesitas filtrar por un rango de años en lugar de un año exacto. YEAR combinado con BETWEEN lo hace natural:

SELECT
    nombre,
    fecha_contratacion,
    YEAR(fecha_contratacion) AS anio
FROM empleados
WHERE YEAR(fecha_contratacion) BETWEEN 2020 AND 2023
ORDER BY fecha_contratacion;
nombrefecha_contratacionanio
Carlos López2020-07-222020
Ana Rodríguez2021-01-102021
Pedro Martínez2022-11-052022
Laura Sánchez2023-06-182023

Esto selecciona todos los empleados contratados entre 2020 y 2023, ambos inclusive. La expresión es más legible que escribir rangos de fechas completos.

YEAR vs EXTRACT(YEAR FROM ...)

Funcionalmente, YEAR() y EXTRACT(YEAR FROM ...) son idénticas:

SELECT
    YEAR('2025-08-15') AS con_year,
    EXTRACT(YEAR FROM '2025-08-15') AS con_extract;
con_yearcon_extract
20252025

La diferencia es puramente estilística. YEAR() es más corta y más habitual en código MySQL. EXTRACT() es estándar SQL y se porta mejor a otros motores de bases de datos. Si tu proyecto solo usa MySQL, YEAR() es perfectamente válida. Si necesitas compatibilidad con PostgreSQL u Oracle, usa EXTRACT.

YEAR con NULL

Si la fecha de entrada es NULL, YEAR devuelve NULL sin generar error:

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

Observa que YEAR('0000-00-00') devuelve 0, no NULL. Esto puede ser relevante si tu tabla tiene fechas con el valor por defecto '0000-00-00', que MySQL permite cuando NO_ZERO_DATE no está activo en el modo SQL.

Combinación con otras funciones

YEAR se combina frecuentemente con MONTH para crear agrupaciones año-mes, o con funciones de agregación para informes complejos:

SELECT
    YEAR(fecha_venta) AS anio,
    MONTH(fecha_venta) AS mes,
    SUM(total) AS ingresos
FROM ventas
WHERE YEAR(fecha_venta) = 2024
GROUP BY YEAR(fecha_venta), MONTH(fecha_venta)
ORDER BY anio, mes;
aniomesingresos
2024162400.00
2024258900.00
2024364700.00
2024471200.00
2024568500.00
2024672300.00

Esta combinación YEAR + MONTH es tan habitual que MySQL ofrece la alternativa EXTRACT(YEAR_MONTH FROM fecha) como atajo. Ambos enfoques son válidos; elige el que resulte más claro para tu equipo.

En el siguiente artículo veremos MONTH para extraer el mes.

Escrito por Eduardo Lázaro