🧚 ¡Oye! Beekeeper Studio es una GUI de bases de datos rápida, moderna y de código abierto Descarga
13 de enero de 2026 Por Matthew Rathbone

DATEDIFF devuelve el número de días, meses u otras unidades entre dos fechas. Cada base de datos lo hace de forma distinta, y los ejemplos cubren PostgreSQL, MySQL, SQLite y SQL Server.

Cómo usar DATEDIFF

DATEDIFF cuenta los días, meses, años u otras unidades desde una fecha de inicio hasta una fecha de fin. Esta es la versión de SQL Server, la que la mayoría tiene en mente:

DATEDIFF(unit, start_date, end_date)
SELECT DATEDIFF(day, '2026-01-01', '2026-03-15');
-- Output: 73

SELECT DATEDIFF(month, '2026-01-01', '2026-03-15');
-- Output: 2

SELECT DATEDIFF(day, '2026-03-15', '2026-01-01');
-- Output: -73

La unidad puede ser year, quarter, month, week, day, hour, minute, second o más pequeña. Si la fecha de fin es anterior a la de inicio, el resultado es negativo.

Con columnas, obtienes una diferencia por fila:

-- Input: orders
-- order_id | order_date | ship_date
-- ---------+------------+-----------
-- 1001     | 2026-02-02 | 2026-02-04
-- 1002     | 2026-02-03 | 2026-02-10
-- 1003     | 2026-02-27 | 2026-03-02
-- 1004     | 2026-03-05 | NULL

SELECT
  order_id,
  order_date,
  ship_date,
  DATEDIFF(day, order_date, ship_date) AS fulfillment_days
FROM orders;

-- Output:
-- order_id | order_date | ship_date  | fulfillment_days
-- ---------+------------+------------+-----------------
-- 1001     | 2026-02-02 | 2026-02-04 | 2
-- 1002     | 2026-02-03 | 2026-02-10 | 7
-- 1003     | 2026-02-27 | 2026-03-02 | 3
-- 1004     | 2026-03-05 | NULL       | NULL

Reglas que debes conocer

  • Cuenta límites, no unidades completas. DATEDIFF(month, ...) cuenta los cambios de mes entre las dos fechas, así que un solo día puede contar como un mes, o como un año:
SELECT DATEDIFF(month, '2026-01-31', '2026-02-01');
-- Output: 1

SELECT DATEDIFF(year, '2025-12-31', '2026-01-01');
-- Output: 1
  • Si entra NULL, sale NULL. Si cualquiera de las fechas es NULL, el resultado también lo es, como en el pedido 1004 de arriba. Envuelve la llamada en COALESCE() cuando necesites un valor predeterminado.

Sintaxis alternativa

MySQL tiene un DATEDIFF de dos argumentos que solo cuenta días y recibe primero la fecha de fin. Para cualquier otra unidad, usa TIMESTAMPDIFF, que recibe primero la fecha de inicio y cuenta unidades completas:

SELECT DATEDIFF('2026-03-15', '2026-01-01');
-- Output: 73

SELECT TIMESTAMPDIFF(MONTH, '2026-01-01', '2026-03-15');
-- Output: 2

PostgreSQL no tiene DATEDIFF. Resta una fecha de otra para obtener los días. Para unidades más grandes, AGE() (con la fecha más reciente primero) devuelve un intervalo en años, meses y días, y EXTRACT saca de él las unidades completas:

SELECT DATE '2026-03-15' - DATE '2026-01-01';
-- Output: 73

SELECT AGE('2026-03-15', '2026-01-01');
-- Output: 2 mons 14 days

SELECT EXTRACT(YEAR FROM AGE('2026-03-15', '2026-01-01')) * 12
     + EXTRACT(MONTH FROM AGE('2026-03-15', '2026-01-01'));
-- Output: 2

SQLite tampoco tiene DATEDIFF. julianday() convierte una fecha en un número de días, así que al restar dos obtienes la diferencia. CAST(... AS INTEGER) elimina la parte decimal, y como no hay unidad de mes ni de año, divide entre 30 o 365 para obtener una aproximación:

SELECT julianday('2026-03-15') - julianday('2026-01-01');
-- Output: 73.0

SELECT CAST((julianday('2026-03-15') - julianday('2026-01-01')) / 30 AS INTEGER);
-- Output: 2

-- The time of day counts: 8 p.m. to 8 a.m. is half a day.
-- Wrap each value in date() to count calendar days instead.
SELECT julianday('2026-03-16 08:00') - julianday('2026-03-15 20:00');
-- Output: 0.5

-- A date it can't read gives NULL, so store dates as YYYY-MM-DD
SELECT julianday('03/15/2026');
-- Output: NULL

¿Cuándo deberías usar DATEDIFF?

La mayoría de las preguntas sobre diferencias de fechas entran en uno de estos cuatro casos.

Medir cuánto tardó algo

Resta una fecha de inicio de una fecha de fin para obtener una duración: los días que tardó en enviarse un pedido, las semanas que duró un proyecto, los minutos que duró una llamada de soporte.

Contar días de retraso o restantes

Compara una fecha límite con hoy, o con una fecha de reporte fija, para ver qué tan atrasado va algo o cuánto tiempo queda. Filtra según el signo del resultado para quedarte con un lado.

Expresar una antigüedad en meses o años

La antigüedad de una cuenta, el tiempo como cliente o los años de servicio necesitan una unidad mayor que los días. Usa una unidad de mes o año si tu base de datos la tiene. En SQLite, divide los días.

Encontrar filas dentro de un rango alrededor de una fecha

Toma el valor absoluto de la diferencia para encontrar filas a cierta cantidad de días de una fecha, antes o después: eventos cerca de un lanzamiento, inicios de sesión alrededor de un incidente.

Ejemplos reales de DATEDIFF

Revisar tickets de soporte contra un SLA

Cada ticket debe resolverse en un máximo de tres días. Cuenta los días que tardó cada uno y marca los incumplimientos (SQLite):

-- Input: support_tickets
-- ticket_id | created_at | resolved_at
-- ----------+------------+------------
-- 301       | 2026-03-02 | 2026-03-03
-- 302       | 2026-03-04 | 2026-03-07
-- 303       | 2026-03-05 | 2026-03-10

SELECT
  ticket_id,
  created_at,
  resolved_at,
  CAST(julianday(resolved_at) - julianday(created_at) AS INTEGER) AS resolution_days,
  CASE
    WHEN julianday(resolved_at) - julianday(created_at) <= 3 THEN 'Within SLA'
    ELSE 'SLA Breach'
  END AS sla_status
FROM support_tickets;

-- Output:
-- ticket_id | created_at | resolved_at | resolution_days | sla_status
-- ----------+------------+-------------+-----------------+-----------
-- 301       | 2026-03-02 | 2026-03-03  | 1               | Within SLA
-- 302       | 2026-03-04 | 2026-03-07  | 3               | Within SLA
-- 303       | 2026-03-05 | 2026-03-10  | 5               | SLA Breach

Listar facturas vencidas

Muestra las facturas que ya pasaron su fecha de vencimiento, empezando por las más atrasadas (MySQL):

-- Input: invoices
-- invoice_id | customer      | due_date
-- -----------+---------------+-----------
-- 5001       | Acme Hardware | 2026-08-15
-- 5002       | Lumen Design  | 2026-09-30
-- 5003       | Acme Hardware | 2026-10-01
-- 5004       | Cedar Clinic  | 2026-10-31

SELECT
  invoice_id,
  customer,
  due_date,
  DATEDIFF(CURDATE(), due_date) AS days_overdue
FROM invoices
WHERE due_date < CURDATE()
ORDER BY days_overdue DESC;

-- Output (run on 2026-10-13):
-- invoice_id | customer      | due_date   | days_overdue
-- -----------+---------------+------------+-------------
-- 5001       | Acme Hardware | 2026-08-15 | 59
-- 5002       | Lumen Design  | 2026-09-30 | 13
-- 5003       | Acme Hardware | 2026-10-01 | 12

Agrupar clientes por cuánto tiempo llevan contigo

Clasifica a los clientes en niveles según su antigüedad en años completos (PostgreSQL):

-- Input: customers
-- customer_name     | signup_date
-- ------------------+------------
-- Northwind Traders | 2022-11-05
-- Bluebird Bakery   | 2025-06-20
-- Fjord Outfitters  | 2025-12-20
-- Kestrel Labs      | 2026-03-02

SELECT
  customer_name,
  signup_date,
  EXTRACT(YEAR FROM AGE(CURRENT_DATE, signup_date)) AS years_with_us,
  CASE
    WHEN AGE(CURRENT_DATE, signup_date) < INTERVAL '1 year' THEN 'New'
    WHEN AGE(CURRENT_DATE, signup_date) < INTERVAL '2 years' THEN 'Established'
    ELSE 'Loyal'
  END AS customer_tier
FROM customers;

-- Output (run on 2026-10-13):
-- customer_name     | signup_date | years_with_us | customer_tier
-- ------------------+-------------+---------------+--------------
-- Northwind Traders | 2022-11-05  | 3             | Loyal
-- Bluebird Bakery   | 2025-06-20  | 1             | Established
-- Fjord Outfitters  | 2025-12-20  | 0             | New
-- Kestrel Labs      | 2026-03-02  | 0             | New

Encontrar suscripciones por renovar

Lista las suscripciones que terminan en los próximos 30 días, con los días restantes (SQL Server). La cláusula WHERE compara subscription_end con un rango de fechas en lugar de envolverla en DATEDIFF, para que se pueda seguir usando un índice sobre la columna.

-- Input: subscriptions
-- customer_name    | subscription_end
-- -----------------+-----------------
-- Harbor Dental    | 2026-10-09
-- Maple Yoga       | 2026-10-20
-- Orbit Analytics  | 2026-11-07
-- Pinecrest Realty | 2027-01-15

SELECT
  customer_name,
  subscription_end,
  DATEDIFF(day, GETDATE(), subscription_end) AS days_remaining
FROM subscriptions
WHERE subscription_end BETWEEN CAST(GETDATE() AS date)
                           AND DATEADD(day, 30, CAST(GETDATE() AS date))
ORDER BY days_remaining;

-- Output (run on 2026-10-13):
-- customer_name   | subscription_end | days_remaining
-- ----------------+------------------+---------------
-- Maple Yoga      | 2026-10-20       | 7
-- Orbit Analytics | 2026-11-07       | 25

Más lecturas sobre DATEDIFF

En este blog:

Documentación oficial:

Beekeeper Studio es un cliente de bases de datos gratuito y de código abierto

La mejor herramienta de consultas y edición de SQL que he usado. Tiene todo lo que necesito para administrar mi base de datos. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio es rápido, intuitivo y fácil de usar. Es compatible con muchísimas bases de datos y funciona de maravilla en Windows, Mac y Linux.

La versión de Beekeeper para Linux tiene el 100% de las funciones, sin recortes ni concesiones.

Lo que dicen los usuarios de Beekeeper Studio

★★★★★
"Beekeeper Studio reemplazó por completo mi antiguo flujo de trabajo con SQL. Es rápido, intuitivo y hace que trabajar con bases de datos vuelva a ser agradable."
— Alex K., desarrollador de bases de datos
★★★★★
"He probado muchas GUI de bases de datos, pero Beekeeper logra el equilibrio perfecto entre funciones y simplicidad. Simplemente funciona."
— Sarah M., ingeniera full stack

¿Listo para mejorar tu flujo de trabajo con SQL?

download Descarga gratis