Hoy vamos a meternos otra vez en el mundo de los datos temporales y a ver cómo sacar partes concretas (por ejemplo, el año, el mes o el día de la semana) usando la función EXTRACT(), y también cómo calcular la edad o los intervalos de tiempo entre fechas con la función AGE().
Trabajar con datos temporales en proyectos reales muchas veces requiere separar partes concretas de una fecha u hora. Por ejemplo:
- Dividir pedidos por años o meses;
- Contar cuántos usuarios se registraron en un día concreto de la semana;
- Analizar cuánto tiempo ha pasado entre dos eventos.
Para resolver este tipo de cosas usamos las funciones EXTRACT() y AGE().
¿Qué es EXTRACT()?
La función EXTRACT() te deja sacar partes concretas de una fecha o timestamp. Por ejemplo, puedes sacar el año de una fecha de nacimiento, ver el número de mes o incluso sacar el día de la semana.
Sintaxis:
EXTRACT(part FROM source)
part: la parte de la fecha que quieres sacar. Puede serYEAR,MONTH,DAY,HOUR,MINUTE,SECONDy más.source: el tipo de dato temporal de donde se saca la info. Puede ser una columna, una constante o el resultado de una función.
Ejemplo 1: sacar año, mes y día
SELECT
EXTRACT(YEAR FROM '2024-11-15'::DATE) AS year_part,
EXTRACT(MONTH FROM '2024-11-15'::DATE) AS month_part,
EXTRACT(DAY FROM '2024-11-15'::DATE) AS day_part;
Resultado:
| year_part | month_part | day_part |
|---|---|---|
| 2024 | 11 | 15 |
Aquí hemos sacado el año, el mes y el día de la fecha 2024-11-15. Este truco viene genial cuando necesitas agrupar datos por partes concretas de la fecha.
Ejemplo 2: día de la semana y hora de una hora
SELECT
EXTRACT(DOW FROM '2024-11-15'::DATE) AS day_of_week,
EXTRACT(HOUR FROM '15:30:00'::TIME) AS hour_part;
Resultado:
| day_of_week | hour_part |
|---|---|
| 3 | 15 |
DOW(Day of Week) devuelve el número del día de la semana: domingo —0, lunes —1, y así sucesivamente.HOURsaca la hora de un valor de tiempo.
Ejemplo 3: usando columnas
Si tienes una tabla con fechas, puedes sacar partes de las fechas para analizarlas. Por ejemplo, imagina que tienes una tabla orders:
| order_id | order_date |
|---|---|
| 1 | 2023-05-12 14:20 |
| 2 | 2023-06-18 10:45 |
| 3 | 2023-07-22 21:15 |
SELECT
order_id,
EXTRACT(MONTH FROM order_date) AS month,
EXTRACT(DAY FROM order_date) AS day
FROM orders;
Resultado:
| order_id | month | day |
|---|---|---|
| 1 | 5 | 12 |
| 2 | 6 | 18 |
| 3 | 7 | 22 |
¿Qué es AGE()?
La función AGE() se usa para calcular la diferencia entre dos timestamps. Por ejemplo, te deja calcular la edad de un cliente a partir de su fecha de nacimiento o ver cuánto tiempo ha pasado desde que se hizo un pedido.
Sintaxis:
AGE(timestamp1, timestamp2)
timestamp1: El timestamp más reciente.timestamp2: El timestamp más antiguo.- Si solo pones un parámetro, PostgreSQL lo compara automáticamente con la fecha actual (
NOW()).
Ejemplo 1: calcular edad
SELECT AGE('2025-11-15'::DATE, '1990-05-12'::DATE) AS age;
Resultado:
| age |
|---|
| 35 years 6 mons |
Este ejemplo muestra la edad de una persona nacida el 12 de mayo de 1990, a fecha de 15 de noviembre de 2025.
Ejemplo 2: intervalo de tiempo entre eventos
SELECT AGE('2023-06-01 15:00'::TIMESTAMP, '2023-05-20 10:30'::TIMESTAMP) AS duration;
Resultado:
| duration |
|---|
| 11 days 4:30:00 |
Aquí hemos calculado el intervalo de tiempo entre dos eventos. Muy útil cuando quieres saber cuánto tiempo ha pasado entre el inicio y el final de una tarea.
Ejemplo 3: edad de un cliente
Imagina que tienes una tabla customers:
| customer_id | birth_date |
|---|---|
| 1 | 1992-03-10 |
| 2 | 1985-07-07 |
Podemos calcular la edad de los clientes:
SELECT
customer_id,
AGE(NOW(), birth_date) AS age
FROM customers;
Resultado a 13 de junio de 2025:
| customer_id | age |
|---|---|
| 1 | 33 years 3 mons |
| 2 | 39 years 11 mons |
Obviamente, tú tendrás tu propio valor de NOW() y tu propio resultado.
Ejemplos prácticos usando EXTRACT() y AGE()
Ahora vamos a juntar las funciones en situaciones reales.
Ejemplo 1: agrupar datos por meses
Imagina que tienes una tabla de pedidos con fechas. Para contar los pedidos por mes, usa esta consulta:
SELECT
EXTRACT(MONTH FROM order_date) AS order_month,
COUNT(*) AS total_orders
FROM orders
GROUP BY order_month
ORDER BY order_month;
Ejemplo 2: días hasta la fecha de caducidad
Imagina que tienes una tabla subscriptions:
| subscription_id | expiry_date |
|---|---|
| 1 | 2023-12-31 |
| 2 | 2024-05-15 |
Queremos saber cuántos días quedan hasta que caduque la suscripción:
SELECT
subscription_id,
AGE(expiry_date, NOW()) AS time_remaining
FROM subscriptions;
Resultado:
| subscription_id | time_remaining |
|---|---|
| 1 | 1 mons 15 days |
| 2 | 6 mons |
Errores típicos y cómo evitarlos
Al usar EXTRACT() y AGE() a veces los que empiezan se encuentran con algunos problemas:
- Intentar sacar una parte que no se puede, por ejemplo, meses de un tipo
TIME. Recuerda: las partesYEAR,MONTHyDAYfuncionan conDATE,TIMESTAMP, pero no conTIME. - Problemas con diferentes formatos de datos temporales. Por ejemplo, la cadena
2023/11/15no se considera una fecha. Usa el casteo con::DATEoTO_DATE(). - Diferencia entre
AGE()y restar timestamps. Si quieres un intervalo exacto (en meses, días, segundos) — usaAGE(), pero si solo quieres el número de días, puedes usar operaciones aritméticas.
Ahora ya tienes todo lo que necesitas para sacar y analizar partes de datos temporales en PostgreSQL. ¡Prueba a jugar con EXTRACT() y AGE() en tus propios proyectos!
GO TO FULL VERSION