Las fechas y horas no son solo números abstractos, sino la clave para una parte valiosa de la información en tus datos. En la vida real te cruzas con fechas todo el rato: por ejemplo, analizar ventas por mes, filtrar por fecha de nacimiento de empleados o comparar intervalos de tiempo. Saber cómo manejar fechas te permite hacer consultas más flexibles y sacar conclusiones analíticas más complejas.
Ejemplos donde trabajar con fechas es súper importante:
- Análisis de ventas en un mes concreto.
- Contar cuántos usuarios se registraron en el último año.
- Crear informes por intervalos de tiempo (por ejemplo, ingresos mensuales).
En PostgreSQL hay un montón de funciones para trabajar con fechas, y ahora vamos a ver solo las más útiles.
Funciones principales para trabajar con fechas y horas
La función NOW() devuelve la fecha y hora actual del servidor de la base de datos. Se usa cuando necesitas saber la hora exacta en este momento. Por ejemplo: quieres guardar la hora de creación de un nuevo registro.
SELECT NOW();
Ejemplo de resultado:
2023-11-05 15:23:45.123456+00
Ejemplo de uso: Quieres insertar un pedido con la fecha y hora actual:
INSERT INTO orders (order_id, order_date, total_amount)
VALUES (1, NOW(), 150.00);
Comentario: aquí
NOW() añadirá automáticamente la fecha y hora actual en la columna
order_date.
Cómo funciona exactamente el operador INSERT lo verás en las próximas lecciones :P
Función CURRENT_DATE
Si solo necesitas insertar la fecha actual sin la hora, usa CURRENT_DATE. Devuelve solo el año, mes y día.
Sintaxis:
SELECT CURRENT_DATE;
Ejemplo de resultado:
2023-11-05
Ejemplo de uso: Supón que quieres obtener los registros del día actual:
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
Comentario: aquí comparamos la fecha de la columna
order_date con la fecha actual.
Un poco de humor. NOW() es como tu café en el curro: listo para ti justo ahora. Y CURRENT_DATE es como el calendario en la pared: solo la fecha, sin detalles extra.
Extraer partes de la fecha con DATE_PART()
La función DATE_PART() nos permite obtener una parte concreta de una fecha, como el año, mes, día, hora o minuto. Esto es útil, por ejemplo, para contar pedidos de un año concreto o saber el día de la semana.
Sintaxis:
DATE_PART('parte', fecha)
Ejemplo:
SELECT DATE_PART('year', NOW()) AS current_year;
Ejemplo de resultado:
| current_year |
|---|
| 2025 |
Partes de la fecha que puedes extraer:
year: año.month: mes.day: día.hour: hora.minute: minuto.second: segundo.dow: día de la semana (0 = domingo).
Ejemplo 2: Extraer el mes de la fecha actual.
SELECT DATE_PART('month', CURRENT_DATE) AS current_month;
Resultado:
| current_month |
|---|
| 6 |
Puedes usar DATE_PART() para cálculos más complejos. Por ejemplo:
Quieres seleccionar solo los usuarios que nacieron en el año actual:
SELECT *
FROM students
WHERE DATE_PART('year', birth_date) = DATE_PART('year', CURRENT_DATE);
Ejemplo de resultado:
| id | first_name | last_name | birth_date | grade |
|---|---|---|---|---|
| 1 | Otto | Art | 2025-03-12 | 9 |
| 2 | Anna | Pal | 2025-07-08 | 8 |
| 3 | Piu | Wolf | 2025-01-22 | 10 |
| 4 | Eva | Go | 2025-09-30 | 7 |
| 5 | Dan | Sok | 2025-06-14 | 9 |
Ejemplos prácticos
En algunos ejemplos verás operadores que aún no has estudiado. No te preocupes, pronto los manejarás como si nada. Solo quiero enseñarte más ejemplos reales. Y también dejarte con un poco de intriga :)
Ejemplo 1: Calcular la edad de un usuario
Supón que tienes una tabla users con la fecha de nacimiento de cada usuario. Queremos calcular su edad.
Consulta:
SELECT user_id, first_name, last_name,
DATE_PART('year', CURRENT_DATE) - DATE_PART('year', birth_date) AS age
FROM users;
Simplemente restamos los años de la fecha actual y la fecha de nacimiento. Es una forma rápida, aunque no exacta, de obtener la edad.
Ejemplo de resultado:
| user_id | first_name | last_name | age |
|---|---|---|---|
| 101 | Alex | Lin | 25 |
| 102 | Maria | Chi | 30 |
| 103 | Tor | Coz | 22 |
| 104 | Nat | Ive | 27 |
| 105 | Don | Sok | 35 |
Ejemplo 2: Filtrar por hora
Si quieres seleccionar todos los pedidos hechos en la última hora:
SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '1 hour';
Fíjate lo cómodo que es usar INTERVAL (intervalo de tiempo).
Ejemplo 3: Agrupar por meses
Quieres contar cuántos pedidos hubo en cada mes del año actual:
SELECT DATE_PART('month', order_date) AS order_month, COUNT(*) AS order_count
FROM orders
WHERE DATE_PART('year', order_date) = DATE_PART('year', CURRENT_DATE)
GROUP BY DATE_PART('month', order_date)
ORDER BY order_month;
La agrupación se hace por el número de mes, y el resultado se ordena por ese mismo número.
Ejemplo de resultado:
| order_month | order_count |
|---|---|
| 1 | 120 |
| 2 | 95 |
| 3 | 134 |
| 4 | 110 |
| 5 | 42 |
Ejemplo 4: Extraer el día de la semana
Quieres saber en qué día de la semana se hacen más pedidos:
SELECT DATE_PART('dow', order_date) AS day_of_week, COUNT(*) AS order_count
FROM orders
GROUP BY DATE_PART('dow', order_date)
ORDER BY order_count DESC;
El comando DATE_PART('dow') devuelve el día de la semana de cada pedido como número, donde 0 es domingo, 1 es lunes, y así sucesivamente. DOW es la abreviatura de DayOfWeek - día de la semana.
Ejemplo de resultado:
| day_of_week | order_count |
|---|---|
| 5 | 210 |
| 4 | 190 |
| 3 | 175 |
| 2 | 160 |
| 1 | 140 |
| 6 | 120 |
| 0 | 95 |
Ojo con los errores típicos
Trabajar con fechas a veces da dolor de cabeza por los errores. Aquí tienes algunos problemas comunes con los que te puedes topar:
Formato de fecha y hora: cuando usas NOW() o cualquier función que devuelve fecha y hora, revisa siempre el formato. Por ejemplo, si comparas order_date con CURRENT_DATE, asegúrate de que la hora se ignora o está bien especificada.
Fecha en formato texto: muchas veces en las bases de datos las fechas se guardan como texto (por ejemplo, string). Si intentas usar funciones para fechas (como DATE_PART()), te dará error. Asegúrate de que los datos son de tipo DATE o TIMESTAMP.
Zonas horarias diferentes: si tu servidor está en una zona horaria y los datos vienen de otra, puede haber líos. Considera usar la zona horaria TIMESTAMPTZ.
GO TO FULL VERSION