SQL query to select dates between two dates
Mastering SQL Queries: Selecting Dates Between Two Dates

Learn how to effectively query and filter data based on date ranges in SQL Server, covering common pitfalls and best practices for various scenarios.
Selecting data within a specific date range is a fundamental operation in database management. Whether you're analyzing sales figures, tracking user activity, or generating reports, filtering by dates is crucial. This article will guide you through the various SQL techniques to achieve this, focusing on SQL Server, but the principles are broadly applicable to other relational database systems.
Basic Date Range Selection with BETWEEN
The most straightforward way to select records between two dates in SQL is by using the BETWEEN
operator. This operator is inclusive, meaning it includes the start and end dates in the result set. It's generally used with DATE
, DATETIME
, or DATETIME2
data types.
SELECT *
FROM YourTable
WHERE YourDateColumn BETWEEN '2023-01-01' AND '2023-01-31';
Basic date range selection using the BETWEEN operator.
BETWEEN
with DATETIME
columns, be aware that it includes the time component. If your end date is '2023-01-31', it will only include records up to '2023-01-31 00:00:00.000'. To include the entire end day, you might need to adjust the end date or use comparison operators.Using Comparison Operators for Precise Control
For more granular control, especially when dealing with DATETIME
or DATETIME2
columns where time components are significant, using comparison operators (>=
and <
or <=
) is often preferred. This method helps avoid issues with the time portion of the end date.
SELECT *
FROM YourTable
WHERE YourDateColumn >= '2023-01-01' AND YourDateColumn < '2023-02-01';
Selecting dates using comparison operators to include the full end day.
In the example above, YourDateColumn < '2023-02-01'
effectively includes all times on '2023-01-31' without needing to specify '2023-01-31 23:59:59.997' (or similar, depending on precision). This is a common and robust pattern.
Handling Date-Only Comparisons with CAST
or CONVERT
If your column is a DATETIME
type but you only care about the date part for filtering, you can CAST
or CONVERT
the column to a DATE
type. However, be cautious as applying functions to a column in the WHERE
clause can prevent the use of indexes, potentially leading to performance issues.
SELECT *
FROM YourTable
WHERE CAST(YourDateColumn AS DATE) BETWEEN '2023-01-01' AND '2023-01-31';
Casting to DATE for date-only comparison (potential performance impact).
CAST
or CONVERT
to the column in the WHERE
clause can make the query non-sargable, meaning indexes on YourDateColumn
might not be used. This can significantly degrade performance on large tables.Best Practice: Sargable Queries for Performance
To ensure optimal performance, especially with large datasets, it's best to write 'sargable' queries. This means structuring your WHERE
clause so that indexes can be utilized. The comparison operator approach (>=
and <
) is generally sargable.
flowchart TD A[Start Query] --> B{Is YourDateColumn indexed?} B -- Yes --> C{Use Sargable WHERE clause} C --> D[YourDateColumn >= 'StartDate' AND YourDateColumn < 'EndDate + 1 day'] D --> E[Efficient Index Seek] B -- No --> F{Consider adding index} F --> G[Full Table Scan (less efficient)] E --> H[Return Results] G --> H
Decision flow for optimizing date range queries.
Example: Selecting Data for the Current Month
A common requirement is to select data for the current month. SQL Server provides functions like GETDATE()
, DATEADD()
, and DATEDIFF()
to dynamically determine date ranges.
DECLARE @CurrentDate DATETIME = GETDATE();
DECLARE @FirstDayOfMonth DATETIME = DATEADD(month, DATEDIFF(month, 0, @CurrentDate), 0);
DECLARE @LastDayOfMonth DATETIME = DATEADD(month, 1, @FirstDayOfMonth);
SELECT *
FROM YourTable
WHERE YourDateColumn >= @FirstDayOfMonth
AND YourDateColumn < @LastDayOfMonth;
Dynamically selecting data for the current month.
This approach calculates the first day of the current month and the first day of the next month, allowing for a sargable comparison that includes all records within the current month, regardless of their time component.