SECOND
La función SECOND extrae el componente de segundos de un valor TIME, DATETIME o TIMESTAMP y lo devuelve como un entero entre 0 y 59. Es la función de extracción temporal con mayor granularidad que ofrece MySQL a nivel de funciones individuales, ya que para trabajar con fracciones de segundo necesitas usar MICROSECOND o EXTRACT(MICROSECOND FROM ...).
Aunque en muchos análisis de negocio basta con agrupar por hora o incluso por minuto, hay escenarios donde los segundos importan: logging de eventos del sistema, análisis de rendimiento de APIs, detección de patrones en datos de alta frecuencia o sincronización de eventos distribuidos. En estos casos, SECOND te proporciona la granularidad necesaria.
Sintaxis
SECOND(expresion_tiempo)El argumento puede ser un valor TIME, DATETIME, TIMESTAMP o una cadena con formato de hora válido. Devuelve un entero de 0 a 59.
Comportamiento básico
SECOND devuelve el componente de segundos de cualquier expresión temporal:
SELECT
SECOND('2025-08-15 14:30:45') AS desde_datetime,
SECOND('09:15:30') AS desde_time,
SECOND('2025-08-15 12:00:00') AS cero_segundos,
SECOND('23:59:59') AS max_segundos;| desde_datetime | desde_time | cero_segundos | max_segundos |
|---|---|---|---|
| 45 | 30 | 0 | 59 |
El resultado es un entero entre 0 y 59. Un datetime que termina en :00 devuelve 0 segundos, y el valor máximo posible es 59. No existe el segundo 60 en MySQL, a diferencia de algunos sistemas que admiten "leap seconds".
SECOND con valores TIME extendidos
Al igual que HOUR y MINUTE, SECOND funciona correctamente con valores TIME que exceden las 24 horas. Los segundos siempre están en el rango 0-59:
SELECT
SECOND('100:30:45') AS duracion_larga,
SECOND('838:59:59') AS maximo_time;| duracion_larga | maximo_time |
|---|---|
| 45 | 59 |
Caso práctico: análisis de tiempos de respuesta
En el monitoreo de APIs y servicios web, los tiempos de respuesta se miden frecuentemente con precisión de segundos. SECOND te permite analizar en qué segundo exacto se registran más eventos:
SELECT
SECOND(fecha_evento) AS segundo,
COUNT(*) AS eventos
FROM log_servidor
WHERE DATE(fecha_evento) = '2025-01-15'
AND HOUR(fecha_evento) = 10
AND MINUTE(fecha_evento) = 0
GROUP BY SECOND(fecha_evento)
ORDER BY eventos DESC
LIMIT 10;| segundo | eventos |
|---|---|
| 0 | 234 |
| 1 | 178 |
| 30 | 145 |
| 2 | 89 |
| 15 | 76 |
| 31 | 72 |
| 3 | 65 |
| 45 | 63 |
| 4 | 58 |
| 5 | 52 |
El pico enorme en el segundo 0 (234 eventos) revela que hay muchos procesos programados que arrancan exactamente a las 10:00:00. El segundo pico en el segundo 30 confirma que también hay tareas alineadas a la media de cada minuto. Este tipo de análisis es imposible sin la granularidad que ofrece SECOND, y es fundamental para detectar cuellos de botella en la infraestructura.
Caso práctico: distribución de inserciones por segundo
Si tu aplicación realiza muchas escrituras en base de datos, analizar la distribución por segundos revela si hay concentraciones que puedan causar bloqueos:
SELECT
SECOND(created_at) AS segundo,
COUNT(*) AS inserciones,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 2) AS porcentaje
FROM transacciones
WHERE DATE(created_at) = '2025-01-15'
GROUP BY SECOND(created_at)
ORDER BY segundo
LIMIT 12;| segundo | inserciones | porcentaje |
|---|---|---|
| 0 | 890 | 4.12 |
| 1 | 412 | 1.91 |
| 2 | 398 | 1.84 |
| 3 | 387 | 1.79 |
| 4 | 375 | 1.74 |
| 5 | 410 | 1.90 |
| 10 | 405 | 1.88 |
| 15 | 425 | 1.97 |
| 20 | 398 | 1.84 |
| 25 | 385 | 1.78 |
| 30 | 678 | 3.14 |
| 31 | 401 | 1.86 |
En una distribución ideal, cada segundo tendría aproximadamente el 1.67% de las inserciones (100% / 60 segundos). Los segundos 0 y 30 están muy por encima de esa media (4.12% y 3.14%), lo que indica que hay procesos batch que se ejecutan en esos momentos exactos. Si estas inserciones causan contención, podrías redistribuirlas añadiendo un retraso aleatorio de unos segundos.
Caso práctico: medir la precisión de eventos programados
Cuando programas tareas para ejecutarse en un momento exacto (como un cron job a las 03:00:00), puedes verificar con qué precisión se ejecutan realmente:
SELECT
nombre_tarea,
hora_programada,
hora_ejecucion_real,
SECOND(hora_ejecucion_real) AS segundo_real,
TIMESTAMPDIFF(SECOND, hora_programada, hora_ejecucion_real) AS desfase_seg
FROM tareas_programadas
WHERE DATE(hora_programada) = '2025-01-15'
ORDER BY desfase_seg DESC
LIMIT 5;| nombre_tarea | hora_programada | hora_ejecucion_real | segundo_real | desfase_seg |
|---|---|---|---|---|
| backup_diario | 2025-01-15 03:00:00 | 2025-01-15 03:00:12 | 12 | 12 |
| sync_inventario | 2025-01-15 06:00:00 | 2025-01-15 06:00:08 | 8 | 8 |
| envio_reportes | 2025-01-15 08:00:00 | 2025-01-15 08:00:05 | 5 | 5 |
| limpieza_cache | 2025-01-15 02:00:00 | 2025-01-15 02:00:03 | 3 | 3 |
| actualizacion_precios | 2025-01-15 07:00:00 | 2025-01-15 07:00:02 | 2 | 2 |
El backup diario tiene un desfase de 12 segundos, que probablemente se debe a la carga del sistema a esa hora. Si la tarea es crítica y el desfase supera un umbral, podrías generar una alerta. SECOND te permite extraer el segundo exacto de ejecución, mientras que TIMESTAMPDIFF calcula el desfase total de forma más precisa.
Caso práctico: reconstruir un timestamp a partir de sus componentes
A veces necesitas descomponer un datetime en todas sus partes y luego reconstruirlo. SECOND junto con las demás funciones de extracción te permite hacerlo:
SELECT
fecha_evento,
YEAR(fecha_evento) AS anio,
MONTH(fecha_evento) AS mes,
DAY(fecha_evento) AS dia,
HOUR(fecha_evento) AS hora,
MINUTE(fecha_evento) AS minuto,
SECOND(fecha_evento) AS segundo,
CONCAT(
YEAR(fecha_evento), '-',
LPAD(MONTH(fecha_evento), 2, '0'), '-',
LPAD(DAY(fecha_evento), 2, '0'), ' ',
LPAD(HOUR(fecha_evento), 2, '0'), ':',
LPAD(MINUTE(fecha_evento), 2, '0'), ':',
LPAD(SECOND(fecha_evento), 2, '0')
) AS reconstruido
FROM log_servidor
LIMIT 3;| fecha_evento | anio | mes | dia | hora | minuto | segundo | reconstruido |
|---|---|---|---|---|---|---|---|
| 2025-01-15 10:30:45 | 2025 | 1 | 15 | 10 | 30 | 45 | 2025-01-15 10:30:45 |
| 2025-01-15 14:22:08 | 2025 | 1 | 15 | 14 | 22 | 8 | 2025-01-15 14:22:08 |
| 2025-01-15 18:05:33 | 2025 | 1 | 15 | 18 | 5 | 33 | 2025-01-15 18:05:33 |
Este ejemplo demuestra que YEAR, MONTH, DAY, HOUR, MINUTE y SECOND son las seis funciones que componen la anatomía completa de un datetime. Juntas, te permiten descomponer, manipular y reconstruir cualquier valor temporal.
SECOND con NULL
SECOND devuelve NULL cuando la entrada es NULL:
SELECT
SECOND(NULL) AS resultado;| resultado |
|---|
| NULL |
El comportamiento es consistente con todas las demás funciones de extracción de fecha: NULL entra, NULL sale, sin errores ni advertencias.
Combinación con otras funciones
SECOND se usa frecuentemente con TIME_TO_SEC para convertir tiempos completos a segundos totales, lo cual facilita los cálculos aritméticos:
SELECT
hora_inicio,
hora_fin,
HOUR(hora_inicio) AS h_ini,
MINUTE(hora_inicio) AS m_ini,
SECOND(hora_inicio) AS s_ini,
TIME_TO_SEC(hora_fin) - TIME_TO_SEC(hora_inicio) AS duracion_segundos,
SEC_TO_TIME(TIME_TO_SEC(hora_fin) - TIME_TO_SEC(hora_inicio)) AS duracion_formato
FROM sesiones_usuario
WHERE DATE(fecha_sesion) = '2025-01-15'
LIMIT 4;| hora_inicio | hora_fin | h_ini | m_ini | s_ini | duracion_segundos | duracion_formato |
|---|---|---|---|---|---|---|
| 09:15:30 | 09:48:12 | 9 | 15 | 30 | 1962 | 00:32:42 |
| 10:02:45 | 10:35:18 | 10 | 2 | 45 | 1953 | 00:32:33 |
| 14:30:00 | 15:12:55 | 14 | 30 | 0 | 2575 | 00:42:55 |
| 16:45:22 | 17:01:08 | 16 | 45 | 22 | 946 | 00:15:46 |
Mientras que SECOND, MINUTE y HOUR te dan las partes individuales, TIME_TO_SEC convierte todo a un número plano de segundos que permite calcular duraciones fácilmente. SEC_TO_TIME hace la conversión inversa para mostrar el resultado en formato legible. Este trío de funciones es fundamental cuando trabajas con duraciones y diferencias de tiempo.
En el siguiente artículo veremos DAYNAME para obtener el nombre del día de la semana.
Escrito por Eduardo Lázaro
