MySQL between clause not inclusive?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
MySQL's BETWEEN clause is inclusive on both ends — it includes rows where the column value equals either boundary. WHERE x BETWEEN 1 AND 10 is equivalent to WHERE x >= 1 AND x <= 10. The common misconception that BETWEEN is not inclusive usually stems from datetime comparisons where the time component causes unexpected filtering. A DATE column compared with BETWEEN '2025-01-01' AND '2025-01-31' works as expected, but a DATETIME column misses records after midnight on January 31st because '2025-01-31' is interpreted as '2025-01-31 00:00:00'.
BETWEEN Is Inclusive
The DATETIME Problem
This is where BETWEEN appears non-inclusive:
The query above misses orders after midnight on January 31st because '2025-01-31' is cast to '2025-01-31 00:00:00'. Only the 08:00:00 record at id=2 would be missed too — actually, all records on Jan 31 after 00:00:00 are excluded except exactly at midnight.
Fix 1: Use the Next Day as Upper Bound
The >= and < pattern is the standard approach for datetime ranges. It includes everything up to but not including the next day.
Fix 2: Use Explicit Time in BETWEEN
This works for DATETIME (1-second precision) but misses fractional seconds if using DATETIME(6). For microsecond precision, use '2025-01-31 23:59:59.999999'.
Fix 3: Use DATE() Function
DATE() strips the time component, so all records on January 31st are included. However, this prevents MySQL from using an index on created_at — the function is applied to every row (full table scan).
Fix 4: Use DATE Column Type
If you only need date precision, use the DATE type instead of DATETIME:
BETWEEN with Integers
Integer BETWEEN behaves exactly as expected — both boundaries are included.
BETWEEN with Strings
String comparison is case-sensitive depending on the column's collation. With utf8_general_ci (case-insensitive), 'a' equals 'A'.
NOT BETWEEN
Index Usage with BETWEEN
Common Pitfalls
- DATETIME implicit cast:
BETWEEN '2025-01-01' AND '2025-01-31'on aDATETIMEcolumn casts the strings to'2025-01-01 00:00:00'and'2025-01-31 00:00:00', excluding most of January 31st. Use>= AND <with the next day instead. - Using DATE() in WHERE:
WHERE DATE(created_at) BETWEEN ...prevents index usage because MySQL cannot use a B-tree index when the column is wrapped in a function. Use range comparisons on the raw column. - BETWEEN with NULL: If the column contains
NULL,BETWEENreturnsNULL(notTRUEorFALSE). NULL rows are excluded from results. UseIS NULLseparately if needed:WHERE (x BETWEEN 1 AND 10) OR x IS NULL. - Reversed boundaries:
BETWEEN 10 AND 1returns no rows — the lower bound must be less than or equal to the upper bound. MySQL does not swap them automatically. - Microsecond precision:
DATETIME(6)stores microseconds.BETWEEN '2025-01-31 00:00:00' AND '2025-01-31 23:59:59'misses records with fractional seconds like23:59:59.500000. Use< '2025-02-01'to be safe.
Summary
- MySQL
BETWEENis inclusive on both ends:x BETWEEN a AND bmeansx >= a AND x <= b - The "not inclusive" issue is almost always a
DATETIMEproblem — date strings cast to midnight - Use
WHERE col >= start AND col < next_dayfor datetime ranges - Avoid
DATE()in WHERE clauses — it prevents index usage BETWEENworks correctly for integers, dates (DATEtype), and strings- Always specify explicit timestamps when comparing against
DATETIME/TIMESTAMPcolumns
Related reading
- MySQL C async methods doesn't work?
- MySQL Cannot Add Foreign Key Constraint
- MySQL Cannot drop index needed in a foreign key constraint
- MySQL Can't create table errno 150
- MySQL case sensitive query
- mysql CHANGE MASTER TO command's MASTER_HOST's length limitation
- mysql check collation of a table
- MySQL Cloning a MySQL database on the same MySql instance

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.