Filtering data based on a date range is an extremely common task when analyzing data in SQL. The BETWEEN
operator provides a convenient way to select rows within a start and end date.
In this comprehensive guide, we‘ll cover everything you need to know to leverage the power of BETWEEN
for querying data between two dates in SQL.
Understanding BETWEEN for Date Filters
The BETWEEN
operator allows you to filter rows where a value falls within a specified range. Here is the basic syntax:
SELECT columns
FROM table
WHERE date_column BETWEEN start_date AND end_date;
This queries for rows where date_column
is greater than or equal to start_date
and less than or equal to end_date
.
Some key characteristics of BETWEEN
:
- Inclusive range – start and end values are included
- Works for dates, numbers, text
- Simpler than chaining multiple comparisons
Overall, BETWEEN
provides a cleaner way to filter dates than stringing together a bunch of >
and <
comparisons.
In terms of dates, you need to format your start and end dates consistently. The standard format is ‘YYYY-MM-DD‘
.
Let‘s move on to some examples of using BETWEEN
for filtering dates.
Filtering by Date Ranges: Practical Examples
BETWEEN
becomes extremely powerful paired with date data to analyze trends over time. Here are some common use cases:
- Filter orders for month-to-date (MTD) reports
- Analyze weekly or monthly user signup trends
- View rolling 28-day retention cohorts
Let‘s go through some detailed examples of using BETWEEN
to filter data by date ranges.
We‘ll start by creating a sample orders
table with some data:
CREATE TABLE orders (
order_id INT,
order_date DATE,
customer_id INT
);
INSERT INTO orders
VALUES
(1, ‘2023-01-01‘, 123),
(2, ‘2023-01-18‘, 456),
(3, ‘2023-01-04‘, 789),
(4, ‘2023-01-11‘, 213);
This contains order data with order_date
spanning January 2023.
Example 1: Basic Date Range Filter
Let‘s start with a simple example fetching all orders between 1/4/2023 and 1/11/2023:
SELECT *
FROM orders
WHERE
order_date BETWEEN ‘2023-01-04‘ AND ‘2023-01-11‘;
This returns orders #3 and #4 based on the date range filter. Simple to filter date ranges!
Example 2: Year-over-Year Analysis
A common analytics use case is comparing performance between years. For example, we could analyze year-over-year (YoY) order totals like this:
SELECT
YEAR(order_date) AS order_year,
SUM(order_total) AS total_orders
FROM orders
WHERE
order_date BETWEEN ‘2022-01-01‘ AND ‘2023-01-31‘
GROUP BY 1;
By filtering between 1/1/2022 and 1/31/2023 before grouping, we can easily compare 2022 vs. 2023 order totals. BIG YoY growth!
This is much cleaner than trying to use multiple YEAR()
checks in the WHERE
clause.
Example 3: Date Range With Other Filter Conditions
A great aspect of BETWEEN
is combining it with other filter criteria. You can filter based on a date window AND/OR other conditions.
Let‘s filter for repeat customers in Dec 2022:
SELECT customer_id, COUNT(*) AS num_orders
FROM orders
WHERE
order_date BETWEEN ‘2022-12-01‘ AND ‘2022-12-31‘
AND customer_id IN (
SELECT customer_id
FROM orders
WHERE order_date < ‘2022-12-01‘
)
GROUP BY 1;
By adding an exists check on past orders, we can view recent repeat purchasers alongside our date filter.
As you can see, the date range capabilities of BETWEEN
pair nicely with other filtering options.
Now that we have some queries under our belt, let‘s compare BETWEEN
to other date range constructs.
BETWEEN vs. Other Date Range Methods
While BETWEEN
makes querying date ranges easy, there are a few other options:
- Using
AND
to chain multiple comparison operators - The
BETWEEN
syntactic equivalent
Let‘s compare them to understand when to use each approach.
BETWEEN vs. Chained Comparison Operators
A common pre-BETWEEN
approach for filtering dates was chaining a bunch of >
and <
together:
SELECT *
FROM orders
WHERE
order_date >= ‘2023-01-01‘
AND order_date <= ‘2023-02-01‘;
This allows you to define an upper and lower bound for a custom date range, similar to BETWEEN
.
However, there are some downsides:
- Verbose – more code
- Harder to visualize the range
- Slower for the optimizer
- More opportunities for logic errors
Overall, BETWEEN
provides cleaner syntax for date ranges.
BETWEEN vs. Equivalent Constructs
An alternative way to express a BETWEEN
filter is by using equivalent syntax with comparison operators:
SELECT *
FROM orders
WHERE
order_date >= ‘2023-01-01‘
AND order_date <= ‘2023-02-01‘
We are simply substituting the BETWEEN
for the same >=
AND <=
logic.
So when should you use each approach?
Generally, prefer simplicity with BETWEEN
. However, complex queries may run faster with the comparison construct variant.
Testing with EXPLAIN
can identify performance differences. Pay attention to:
- Number of key lookups
- Range scanned on indexes
If performance is no issue, I suggest sticking with BETWEEN
for code clarity.
Best Practices for Querying Between Dates
When filtering date ranges with BETWEEN
, follow these best practices:
- Use consistent date formats – Stick to YYYY-MM-DD dates
- Validate date ranges – Ensure the start <= end
- Index date columns – Speed up range scans significantly
- Test complex queries – Compare plans to equivalent logic
- Watch out for time components – Dates have times too!
Following those tips will help optimize date filtering performance.
Let‘s conclude by summarizing the key points around using SQL BETWEEN
with dates.
Summary
Here is a quick recap of what we covered in this guide:
- BETWEEN allows querying data between a start and end value
- Works great for filtering date ranges when formatted as YYYY-MM-DD
- Very useful for analyzing trends over time
- Can combine date filters with other WHERE criteria
- Provides simpler syntax than chaining multiple comparisons
- Make sure to index dates for good performance
Filtering by a date range is an extremely common task for data analysis. Using SQL‘s BETWEEN
operator makes it easy to query data between two dates.
Now you have all the knowledge to leverage BETWEEN
for investigating trends spanning periods of time in your data warehouse, application, analytics, and reporting.
Put this powerful date range querying capability to work across all your SQL-based analysis!