SQL Server’s DATETIME
data type stores both date and time information. While this precision is often useful, there are times when you only need to query based on the date portion, ignoring the time. This tutorial explains how to effectively query DATETIME
fields based solely on the date.
The Challenge
Directly comparing a DATETIME
field to a date string (e.g., ’03/19/2014′) often doesn’t work as expected. SQL Server treats the comparison as requiring a match for both date and time, so unless the time component also matches, no rows will be returned.
Solutions
Here are several methods to query DATETIME
fields by date:
1. Using CAST
to Convert to DATE
The most straightforward and recommended approach is to convert the DATETIME
field to a DATE
data type using the CAST
function. This effectively removes the time portion, allowing a direct comparison with a date string.
SELECT *
FROM test
WHERE CAST([date] AS DATE) = '2014-03-19';
Important: Note the date format ‘YYYY-MM-DD’. While SQL Server can often implicitly convert from other formats, it’s best practice to use this standard format to avoid ambiguity and potential errors.
2. Using BETWEEN
for a Date Range
You can specify a range of times within the desired date using the BETWEEN
operator. This is particularly useful when you want to include all records from a specific date, regardless of the time.
SELECT *
FROM test
WHERE [date] BETWEEN '2014-03-19' AND '2014-03-19 23:59:59';
Be cautious with this method, especially if your DATETIME
field has higher precision (e.g., milliseconds). The upper bound might not include all values on the last second of the day.
3. Utilizing DATEADD
and DATEDIFF
This approach involves calculating the beginning and end of the target date.
SELECT *
FROM test
WHERE [date] >= DATEADD(day, DATEDIFF(day, 0, '2014-03-19'), 0)
AND [date] < DATEADD(day, DATEDIFF(day, 0, '2014-03-19') + 1, 0);
This method is more verbose but can be useful in more complex scenarios. DATEDIFF(day, 0, '2014-03-19')
calculates the number of days between January 1, 1900 (represented by 0
in SQL Server) and the target date. DATEADD
then uses this difference to determine the beginning and end of the day.
4. Extracting Date Components
You can extract the year, month, and day components from the DATETIME
field and compare them individually.
SELECT *
FROM test
WHERE YEAR([date]) = 2014
AND MONTH([date]) = 3
AND DAY([date]) = 19;
While this works, it’s generally less efficient and readable than using CAST
or a date range.
5. Creating a Computed Column
If you frequently need to query by date, consider adding a computed column to your table that stores only the date portion.
ALTER TABLE test
ADD DateOnly AS CAST([date] AS DATE);
You can then query this computed column directly:
SELECT *
FROM test
WHERE DateOnly = '2014-03-19';
This approach improves query performance and code readability, but it requires modifying your table schema.
Best Practices
- Use a standard date format: Employ ‘YYYY-MM-DD’ for consistency and to avoid ambiguity.
- Consider performance: For frequently executed queries, computed columns can significantly improve performance.
- Choose the most readable approach: Prioritize clarity and maintainability in your code.
CAST
is often the most straightforward and recommended solution. - Be mindful of precision: If your
DATETIME
field has high precision (milliseconds), use caution withBETWEEN
and ensure your upper bound includes all possible values.