sqlpostgresqlmysqldates

NOW, CURRENT_DATE y aritmetica con INTERVAL en SQL

Como filtrar filas de los ultimos 7 dias y del mes actual con NOW(), CURRENT_DATE y aritmetica de INTERVAL en PostgreSQL, MySQL y ClickHouse.

3 min de lecturaReferencesql · postgresql · mysql · dates · interval · clickhouse

Casi toda consulta analitica empieza con "los ultimos N dias" o "el mes actual". Para que esos filtros sean correctos y rapidos hay que saber en que se diferencia NOW() de CURRENT_DATE, y como sumar intervalos a las fechas.

NOW() y CURRENT_DATE: que devuelven

PostgreSQL ofrece dos formas basicas de pedir "ahora":

  • NOW() (alias CURRENT_TIMESTAMP) devuelve un timestamptz — un momento con fecha y hora.
  • CURRENT_DATE devuelve un date — solo el dia de hoy, sin hora.
SELECT
    NOW()          AS ts,          -- 2026-06-17 14:30:00+00
    CURRENT_DATE   AS today,       -- 2026-06-17
    CURRENT_TIME   AS clock;       -- 14:30:00+00

La diferencia importa al comparar. created_at >= CURRENT_DATE conserva todo desde la medianoche de hoy, mientras que created_at >= NOW() solo deja el futuro, que casi nunca es lo que buscas.

La ventana de "los ultimos 7 dias"

El patron canonico resta un intervalo al momento actual:

SELECT id, email, created_at
FROM users
WHERE created_at >= NOW() - INTERVAL '7 days'
ORDER BY created_at DESC;

INTERVAL '7 days' es un literal de duracion. Puedes sumarlo o restarlo a cualquier timestamp o date. Admite hours, days, months, years y combinaciones como INTERVAL '1 day 6 hours'.

El mismo truco escala a los agregados — ingresos del ultimo dia, desglosados por estado:

SELECT status, COUNT(*) AS cnt, SUM(amount) AS revenue
FROM orders
WHERE created_at >= NOW() - INTERVAL '24 hours'
GROUP BY status;

Detalle util: el lado derecho es constante por consulta, asi que el planificador lo evalua una vez y aun puede usar un indice sobre created_at.

"El mes actual" y truncar al limite

Para ventanas de calendario, date_trunc recorta un timestamp al inicio de un periodo:

SELECT id, amount
FROM orders
WHERE created_at >= date_trunc('month', CURRENT_DATE)
  AND created_at <  date_trunc('month', CURRENT_DATE) + INTERVAL '1 month';

Es mas robusto que EXTRACT(MONTH FROM created_at) = 6: el limite superior se ajusta solo a la duracion del mes y la consulta sigue siendo sargable (usa indice). La misma forma sirve para 'day', 'week' y 'year'.

NOW() frente a clock_timestamp()

El matiz clave: NOW() se fija al inicio de la transaccion y no cambia hasta que esta termina. Todas las llamadas dentro de una misma transaccion devuelven el mismo valor.

BEGIN;
SELECT NOW();              -- 14:30:00
-- ... trabajo largo ...
SELECT NOW();              -- sigue siendo 14:30:00
SELECT clock_timestamp();  -- hora real del reloj, ya avanzo
COMMIT;
  • NOW() / CURRENT_TIMESTAMP / transaction_timestamp() — hora de inicio de la transaccion.
  • statement_timestamp() — inicio de la sentencia actual.
  • clock_timestamp() — reloj real, cambia en cada llamada.

Para la logica de negocio y los filtros usa NOW(): el valor es estable y reproducible. clock_timestamp() solo sirve para medir tiempos dentro de una sola transaccion.

Gotcha: no envuelvas la columna en una funcion solo para compararla. WHERE date_trunc('day', created_at) = CURRENT_DATE desactiva el indice sobre created_at. Compara la columna desnuda contra los limites: created_at >= CURRENT_DATE AND created_at < CURRENT_DATE + INTERVAL '1 day'.

Diferencias de MySQL y ClickHouse

MySQL escribe los intervalos de otra forma — sin comillas y con unidades en singular:

-- MySQL
SELECT id, email
FROM users
WHERE created_at >= NOW() - INTERVAL 7 DAY;

SELECT CURDATE() AS today, NOW() AS ts;
  • En MySQL, CURDATE() es el analogo de CURRENT_DATE, y la unidad se escribe INTERVAL 7 DAY (DAY, HOUR, MONTH, sin s).
  • El NOW() de MySQL tambien es estable dentro de una sentencia; el reloj en vivo lo da SYSDATE().
  • ClickHouse usa now() con ayudantes como subtractDays(now(), 7) o now() - INTERVAL 7 DAY; el inicio de mes es toStartOfMonth(now()).

Recuerda tres cosas: NOW() es el timestamp del tiempo de transaccion, CURRENT_DATE es solo fecha, y la aritmetica de intervalos sobre una columna desnuda da ventanas temporales correctas y rapidas.

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador