BETWEEN 是闭区间,包含左右边界值;WHERE age BETWEEN 25 AND 30 等价于 age >= 25 AND age <= 30;日期比较需注意精度,created_at >= '2024-01-01' 会匹配当天全部时间。

BETWEEN 是闭区间,包含左右边界值
写 WHERE age BETWEEN 25 AND 30 就是查 age >= 25 AND age ,25 和 30 都会被命中。这不是“通常包含”,而是 SQL 标准强制行为——所有主流数据库(MySQL、PostgreSQL、SQL Server、Oracle)都严格遵循。
为什么你查不到边界值?常见原因
现象:表里明明有 age = 25 的记录,但 age BETWEEN 25 AND 30 没返回。
- 字段实际是字符串类型(如
VARCHAR),导致字典序比较:'100'会落在'25'和'30'之间 - 字段含
NULL值:BETWEEN 对NULL永远返回UNKNOWN,该行直接被过滤(不报错、不提示) - 日期字段带时间部分,但只写了日期字符串:
created_at BETWEEN '2024-01-01' AND '2024-01-31'实际只覆盖到'2024-01-31 00:00:00',漏掉当天其他时间点 - 左右边界顺序反了:
BETWEEN 30 AND 25在 MySQL 中不报错但返回空集(SQL Server 直接报错)
日期范围查询必须注意精度
如果字段是 DATETIME 或 TIMESTAMP,用 BETWEEN 容易漏数据。
-
created_at BETWEEN '2024-01-01' AND '2024-01-31'→ 实际等价于created_at >= '2024-01-01 00:00:00' AND created_at - 正确做法是左闭右开:
created_at >= '2024-01-01' AND created_at - 若坚持用 BETWEEN 且字段是纯
DATE类型(无时间),则BETWEEN '2024-01-01' AND '2024-01-31'安全;但一旦字段类型含时间,就别硬套
不同数据库对边界表达式的处理差异
BETWEEN 本身不支持表达式作为边界,比如 score BETWEEN avg_score - 5 AND avg_score + 5 在多数引擎中非法。
- PostgreSQL 支持
BETWEEN SYMMETRIC,允许颠倒左右值顺序:id BETWEEN SYMMETRIC 100 AND 1等价于id BETWEEN 1 AND 100 - MySQL 不支持
SYMMETRIC,需手动兜底:WHERE col >= LEAST(@a, @b) AND col - SQL Server 没有
LEAST/GREATEST,得用IIF或子查询 - 所有数据库中,BETWEEN 的左右值类型必须兼容,否则 MySQL 可能静默转成 0,PostgreSQL 直接报错
operator does not exist
真正影响结果的从来不是语法像不像,而是字段类型、NULL 分布、时间精度和执行计划里实际走的索引路径——跑完 SQL 后,一定要用真实数据验证边界是否真被包含。

















