BETWEEN包含边界值且要求类型一致,因此WHERE price BETWEEN 10 AND 20查不到NULL(三值逻辑中NULL比较结果为UNKNOWN)或字符串(类型不匹配导致转换错误或静默失败)。

BETWEEN 包含边界值,且要求左右操作数类型一致
为什么 WHERE price BETWEEN 10 AND 20 查不到 NULL 或字符串?
BETWEEN 是语法糖,等价于 column >= low_value AND column 。如果 <code>price 列含 NULL,该行直接被排除(因为 NULL >= 10 结果为 UNKNOWN);若列是字符串类型(如 '$15.99'),而你用数字比较,多数数据库会报类型转换错误或静默失败。
- 确保列数据类型与边界值一致:数值列配数字,日期列配
DATE字面量(如'2023-01-01') - 想包含
NULL需显式加条件:WHERE (price BETWEEN 10 AND 20) OR price IS NULL - 字符串字段慎用 BETWEEN:除非明确按字典序比较(如
status BETWEEN 'active' AND 'pending'),否则优先用IN或正则
日期范围查询中 BETWEEN 容易漏掉当天的全部时间点
当列是 DATETIME 或 TIMESTAMP 类型,created_at BETWEEN '2023-01-01' AND '2023-01-31' 实际只查到 '2023-01-31 00:00:00',漏掉当天 00:00:01 之后的数据。
- 安全写法是用开闭区间:
created_at >= '2023-01-01' AND created_at - 若坚持用 BETWEEN,请补全时间部分:
BETWEEN '2023-01-01 00:00:00' AND '2023-01-31 23:59:59'(注意秒级精度可能丢失毫秒) - PostgreSQL 支持
tsrange类型,MySQL 8.0+ 可配合TIMESTAMPADD动态计算右边界
BETWEEN 在索引使用上不如显式 >= AND
虽然语义等价,但某些旧版本数据库优化器对 BETWEEN 的索引选择不够稳定,尤其在复合索引场景下。
- 例如联合索引
(category, price),WHERE category = 'book' AND price BETWEEN 20 AND 50通常能走索引;但WHERE price BETWEEN 20 AND 50 AND category = 'book'在部分 MySQL 版本中可能无法利用索引前缀 - 建议把等值条件放前面,范围条件放后面,并统一用
>=和显式书写,避免优化器误判 - 执行前务必用
EXPLAIN确认是否命中索引,特别是数据量超过 10 万行时
边界值是否包含、类型是否隐式转换、时间精度是否截断——这三个点不手动验证,BETWEEN 就容易查出“明明该有却没出来”的结果。

















