How to Filter by Today’s Date in SQL Server (And the Mistake Most Beginners Make)

Filtering records by today’s date sounds simple enough, but there’s a gotcha that’s easy to miss if you’re not careful. This article starts with the correct approach, then explains why the obvious method fails. So you’ll know what to do and why.

The Right Way to Filter by Today’s Date

The approach you use depends on whether your column is a DATE type or a DATETIME/DATETIME2 type.

If Your Column Is a DATE Type

DATE column stores no time component, so a simple equality comparison works. The only thing to watch is that GETDATE() returns a datetime value, so you’ll need to cast it to DATE first to match the column type.

SELECT *
FROM orders
WHERE order_date = CAST(GETDATE() AS DATE);

If Your Column Is a DATETIME or DATETIME2 Type

DATETIME or DATETIME2 column stores both date and time, so a direct equality comparison won’t work reliably. The correct approach is to filter by a range covering the full 24-hour window:

SELECT *
FROM orders
WHERE order_date >= CAST(GETDATE() AS DATE)
  AND order_date < DATEADD(day, 1, CAST(GETDATE() AS DATE));

This captures every row from midnight at the start of today through to the last millisecond before midnight tonight, regardless of what time each record was created.

This range approach also works perfectly fine on DATE columns, so if you want a single consistent query regardless of column type, this is the one to use.

If you’re not sure whether your column is a DATE type or a DATETIME/DATETIME2 type, you can check with this query:

SELECT
COLUMN_NAME,
DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'orders'
AND COLUMN_NAME = 'order_date';

The Mistake Most Beginners Make (With DATETIME Columns)

The instinctive approach is to compare the column directly against GETDATE():

SELECT *
FROM orders
WHERE order_date = GETDATE();

On a DATE column this actually works. SQL Server handles the implicit conversion and matches on the date portion only. But on a DATETIME or DATETIME2 column, this almost never returns any rows.

The reason is that GETDATE() returns the current date and time down to the millisecond. This could look something like 2026-06-24 09:15:30.123. For a row to match, its order_date would need to be exactly 2026-06-24 09:15:30.123 (the same year, month, day, hour, minute, second, and millisecond). The chance of that happening is almost zero. It would require a row to have been created at the exact millisecond the query runs. Any row created even a millisecond earlier or later won’t match.

But the biggest issue is that there’s no error message. The query runs fine and simply returns zero rows, which makes it a particularly easy mistake to miss.

Why Not Just Convert the Column to DATE?

You might see an alternative approach online that strips the time from the column itself:

SELECT *
FROM orders
WHERE CAST(order_date AS DATE) = CAST(GETDATE() AS DATE);

This works, but it’s slower on large tables. Casting GETDATE() as DATE is fine because SQL Server evaluates it once and treats the result as a fixed value. Converting/casting the column itself is the problem. It forces SQL Server to evaluate the function on every single row before it can apply the filter, which prevents it from using an index on order_date efficiently.

The range approach in the recommended solution keeps the column untouched on the left side of the comparison, so any index on order_date can be used as normal. This makes it a sargable query.

Other Useful Variations

Records From Yesterday

SELECT *
FROM orders
WHERE order_date >= DATEADD(day, -1, CAST(GETDATE() AS DATE))
  AND order_date < CAST(GETDATE() AS DATE);

Records From Tomorrow

SELECT *
FROM bookings
WHERE booking_date >= DATEADD(day, 1, CAST(GETDATE() AS DATE))
  AND booking_date < DATEADD(day, 2, CAST(GETDATE() AS DATE));

Records From Today Onwards

SELECT *
FROM bookings
WHERE booking_date >= CAST(GETDATE() AS DATE);

Records Up to and Including Today

SELECT *
FROM orders
WHERE order_date < DATEADD(day, 1, CAST(GETDATE() AS DATE));

Quick Reference

GoalQuery Pattern
Today (DATE column)WHERE order_date = CAST(GETDATE() AS DATE)
Today (DATETIME column)WHERE order_date >= CAST(GETDATE() AS DATE) AND order_date < DATEADD(day, 1, CAST(GETDATE() AS DATE))
YesterdayWHERE order_date >= DATEADD(day, -1, CAST(GETDATE() AS DATE)) AND order_date < CAST(GETDATE() AS DATE)
TomorrowWHERE order_date >= DATEADD(day, 1, CAST(GETDATE() AS DATE)) AND order_date < DATEADD(day, 2, CAST(GETDATE() AS DATE))
Today onwardsWHERE order_date >= CAST(GETDATE() AS DATE)
Up to and including todayWHERE order_date < DATEADD(day, 1, CAST(GETDATE() AS DATE))