SQL BETWEEN: Filter a Range of Numbers, Dates or Text
The SQL BETWEEN operator selects values inside a range, and both ends of the range are included. price BETWEEN 100 AND 200 means exactly the same as price >= 100 AND price <= 200.
What Is SQL BETWEEN?
BETWEEN is used in a WHERE clause to keep rows whose value falls inside a range. This query lists products priced from 100 to 200:
SELECT name, category, price
FROM products
WHERE price BETWEEN 100 AND 200
ORDER BY price
LIMIT 6;
▶ Run this query in the SQL Playground
| name | category | price |
|---|---|---|
| Artisan Hot Sauce Trio | Food & Beverage | 104.33 |
| Smart Thermostat | Home & Garden | 115.69 |
| A5 Hardcover Notebook 3pk | Office Supplies | 123.26 |
| Play Kitchen Deluxe | Toys | 154.36 |
| Hydrating Face Moisturizer | Health & Beauty | 160.75 |
| Zero to One (Thiel) | Books | 163.35 |
SELECT columns
FROM table_name
WHERE column_name BETWEEN low_value AND high_value;
The lower value is written first. BETWEEN works with numbers, dates and text.
BETWEEN Includes Both Ends
BETWEEN is shorthand for two comparisons joined with AND. Counting the same range both ways gives the same answer:
SELECT
(SELECT COUNT(*) FROM products WHERE price BETWEEN 100 AND 200) AS with_between,
(SELECT COUNT(*) FROM products WHERE price >= 100 AND price <= 200) AS with_comparisons;
▶ Run this query in the SQL Playground
| with_between | with_comparisons |
|---|---|
| 7 | 7 |
Both columns show 7. A product priced at exactly 100 or exactly 200 is included in either version.
BETWEEN With Dates
Date ranges are the most common use. This query counts the orders placed in the first quarter of 2024 and adds up their value:
SELECT COUNT(*) AS orders,
ROUND(SUM(total), 2) AS revenue
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-03-31';
▶ Run this query in the SQL Playground
| orders | revenue |
|---|---|
| 22 | 49866.49 |
BETWEEN '2024-01-01' AND '2024-03-31' stops at midnight at the start of 31 March, so rows from later that day are left out. For date-time columns use a half-open range instead: order_time >= '2024-01-01' AND order_time < '2024-04-01'. In the Playground, order_date holds a date only, so BETWEEN is safe.NOT BETWEEN
NOT BETWEEN returns the rows outside the range. Here it finds salaries below 60,000 or above 150,000:
SELECT first_name, last_name, department, salary
FROM employees
WHERE salary NOT BETWEEN 60000 AND 150000
ORDER BY salary DESC
LIMIT 6;
▶ Run this query in the SQL Playground
| first_name | last_name | department | salary |
|---|---|---|---|
| Steven | Nguyen | Marketing | 204449 |
| Nancy | Thompson | Customer Success | 203999 |
| John | Lee | Operations | 203467 |
| Donna | Johnson | Engineering | 199029 |
| Matthew | Wilson | Marketing | 196530 |
| Paul | Robinson | Finance | 196032 |
Because BETWEEN includes both ends, NOT BETWEEN excludes them: a salary of exactly 60,000 is not returned.
BETWEEN With Text
With text, BETWEEN compares values in alphabetical order. That makes the upper end easy to get wrong. Which initials does this range return?
SELECT DISTINCT SUBSTR(last_name, 1, 1) AS initial
FROM employees
WHERE last_name BETWEEN 'A' AND 'C'
ORDER BY initial;
▶ Run this query in the SQL Playground
| initial |
|---|
| A |
| B |
A name such as "Clark" sorts after the single letter "C", so it falls outside the range. To include every name that starts with C, extend the upper bound (BETWEEN 'A' AND 'Cz') or, more clearly, use last_name >= 'A' AND last_name < 'D'.
Common BETWEEN Mistakes
Three ways a BETWEEN filter returns the wrong rows.
1. Writing the larger value first
SELECT name, price
FROM products
WHERE price BETWEEN 200 AND 100;
SELECT name, price
FROM products
WHERE price BETWEEN 100 AND 200;
BETWEEN 200 AND 100 asks for values that are at least 200 and at most 100, which is impossible, so the result is empty and no error is raised. (PostgreSQL offers BETWEEN SYMMETRIC, which accepts either order.)
2. Using a date as the end of a date-time range
WHERE created_at BETWEEN '2024-03-01'
AND '2024-03-31'
WHERE created_at >= '2024-03-01'
AND created_at < '2024-04-01'
When the column holds a timestamp, the end value is read as midnight, so everything after 00:00 on the last day is excluded.
3. Expecting BETWEEN to exclude the ends
WHERE age BETWEEN 18 AND 65
WHERE age > 18 AND age < 65
BETWEEN always includes both boundary values. When a boundary must be left out, write the comparisons yourself.
Practice BETWEEN Queries
4 exercises on the real Playground tables.
Write each query yourself first. Every solution has been run against the Playground database.
-
1Easy How many products have a rating from 4.0 to 4.5? Table:
productsShow solution
SELECT COUNT(*) AS products FROM products WHERE rating BETWEEN 4.0 AND 4.5;▶ Run this query in the SQL Playground
Both 4.0 and 4.5 are included in the range.
-
2Easy List employees hired during 2022, earliest first. Show ten rows. Table:
employeesShow solution
SELECT first_name, last_name, hire_date FROM employees WHERE hire_date BETWEEN '2022-01-01' AND '2022-12-31' ORDER BY hire_date LIMIT 10;▶ Run this query in the SQL Playground
hire_datestores a date with no time, so the last day of the year is fully included. -
3Medium Count orders with a total outside the range 100 to 1,000, grouped by status. Table:
ordersShow solution
SELECT status, COUNT(*) AS orders FROM orders WHERE total NOT BETWEEN 100 AND 1000 GROUP BY status ORDER BY orders DESC;▶ Run this query in the SQL Playground
NOT BETWEEN keeps totals below 100 or above 1,000; GROUP BY then counts them per status.
-
4Medium Find orders placed in December 2024 with a total between 500 and 2,000. Table:
ordersShow solution
SELECT id, order_date, total FROM orders WHERE order_date BETWEEN '2024-12-01' AND '2024-12-31' AND total BETWEEN 500 AND 2000 ORDER BY order_date, id;▶ Run this query in the SQL Playground
Two BETWEEN conditions joined with AND: one for the date range and one for the amount.
📝 Quiz — BETWEEN
Test your understanding · 0/5 answered
Which rows does "price BETWEEN 10 AND 20" return?
BETWEEN is inclusive: it is the same as price >= 10 AND price <= 20.
What does "price BETWEEN 20 AND 10" return in most databases?
It asks for values that are at least 20 and at most 10. No value satisfies both, so nothing is returned.
A column stores timestamps. Which filter returns all of March 2024?
The half-open range includes every moment of 31 March. BETWEEN with a date as the end stops at midnight.
How do you select values outside a range?
NOT BETWEEN low AND high returns values below low or above high.
Does last_name BETWEEN 'A' AND 'C' return the name 'Clark'?
Text is compared alphabetically, and 'Clark' comes after the single letter 'C', so it is outside the range.
BETWEEN Interview Questions
Q1. Is BETWEEN inclusive or exclusive?
Inclusive at both ends. x BETWEEN a AND b is equivalent to x >= a AND x <= b.
Q2. Why can BETWEEN be risky with date-time columns?
A date written without a time is treated as midnight. Used as the upper bound, it excludes the rest of that day. A half-open range, >= start AND < next_day, avoids the problem.
Q3. How does BETWEEN treat NULL?
If the tested value or either bound is NULL, the result is unknown and the row is not returned. Use IS NULL to find missing values.
Frequently Asked Questions
Is SQL BETWEEN inclusive?
Yes. BETWEEN includes both the lower and the upper value. BETWEEN 1 AND 5 returns 1, 2, 3, 4 and 5.
Can I use BETWEEN with dates?
Yes. Write the dates in the format your database expects, for example BETWEEN '2024-01-01' AND '2024-12-31'. If the column also stores a time, use >= and < with the day after the end date instead.
What is the difference between BETWEEN and IN?
BETWEEN matches a continuous range between two values. IN matches a list of specific values.
Does the order of the values in BETWEEN matter?
Yes. The lower value must come first. If the values are reversed, most databases return no rows.