MySQL的BETWEEN是闭区间操作符,包含边界值;但时间字段需注意时区、精度及隐式补零问题,推荐用>=和

MySQL 的 BETWEEN 是否包含边界值
包含。MySQL 中的 BETWEEN 是**闭区间**操作符,等价于 value >= min AND value ,左右边界都参与匹配。
BETWEEN 在 WHERE 子句中的实际行为
它常用于数值、日期、字符串范围过滤,但要注意类型隐式转换和排序规则的影响:
- 对
INT或DATE类型,边界包含是确定的,例如id BETWEEN 1 AND 3会返回1、2、3 - 对字符串(如
VARCHAR),比较基于当前列的COLLATION,可能因大小写或空格处理导致意外结果 - 如果
min > max(比如5 BETWEEN 10 AND 1),整个表达式恒为FALSE,不会报错但不返回数据
SELECT * FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31';
该语句包含 '2024-01-01 00:00:00' 和 '2024-01-31 00:00:00',但不包含 '2024-01-31 23:59:59' —— 因为时间部分未显式指定,默认补零。
容易被忽略的时区与精度陷阱
当字段是 DATETIME 或 TIMESTAMP 时,BETWEEN 的边界行为受以下因素干扰:
-
TIMESTAMP会自动转为系统时区再比较,而DATETIME不做时区转换 - 若字段含微秒(如
DATETIME(6)),而字面量没写精度(如'2024-01-01'),MySQL 会补零到最低位,可能漏掉毫秒级数据 - 使用函数包裹(如
BETWEEN DATE(start_time) AND DATE(end_time))会导致索引失效
SELECT * FROM events
WHERE event_time BETWEEN '2024-01-01 00:00:00.000000'
AND '2024-01-01 23:59:59.999999';替代写法更可控的场景
当需要明确控制开闭性、避免隐式转换或提升可读性时,建议显式用 >= 和 :
- 查询“当天全部数据”:用
WHERE dt >= '2024-01-01' AND dt 比BETWEEN更安全 - 配合索引优化:范围查询中,
可更好利用 B+ 树索引的右边界截断能力 - 处理 NULL:
BETWEEN NULL AND 10恒为NULL(即不匹配),而col 仍可能命中非 NULL 值
边界包含本身没问题,但真正出问题的,往往是没意识到时间精度、时区、字符排序这些“默认行为”。










