DATEDIFF() returns the number of specified datepart boundaries crossed between two dates.
DATEDIFF() counts how many datepart boundaries (day, month, year, etc.) occur between a start date and an end date. It returns an integer that can be positive, zero, or negative.
Place the desired datepart first, followed by the earlier date, then the later date. The order matters: DATEDIFF(day, startdate, enddate)
returns positive numbers when enddate
is after startdate
.
SELECT c.id, DATEDIFF(day, c.created_at, o.order_date) AS days_to_first_order
FROM Customers c
JOIN Orders o ON o.customer_id = c.id
WHERE o.order_date = (SELECT MIN(order_date) FROM Orders WHERE customer_id = c.id);
Common dateparts include millisecond
, second
, minute
, hour
, day
, week
, month
, quarter
, and year
. Use abbreviations like dd
, wk
, or yy
interchangeably.
Wrap DATEDIFF() in a WHERE
clause. Example: find orders shipped more than 7 days after placement: SELECT * FROM Orders WHERE DATEDIFF(day, order_date, shipped_date) > 7;
Use year
as the datepart and pass the birthdate first: SELECT DATEDIFF(year, birthdate, GETDATE()) AS age_years FROM Customers;
. For precise ages, compare month/day portions separately.
Index date columns for faster filtering. Always choose the smallest necessary datepart (e.g., hours instead of minutes) to avoid large numbers. Confirm time-zone consistency to prevent off-by-one errors.
DATEDIFF() counts boundaries crossed, not elapsed time, so DATEDIFF(day, '2024-06-01', '2024-06-02')
returns 1 even though only 24 hours pass.
DATEDIFF() uses stored datetime values without adjusting for client time zones. Convert all timestamps to UTC or the same zone before comparison.
DATEDIFF() only returns integers. For fractional days, divide the difference in minutes or seconds by 1440 or 86400, or use DATEDIFF_BIG
with microsecond
for higher precision.