mysql中BETWEEN操作符进行范围查询的使用

BETWEEN是闭区间,包含边界值,严格等价于col >= low AND col

mysql中between操作符进行范围查询的使用

MySQL中BETWEEN是闭区间,包含边界值

很多人误以为BETWEEN是“左开右闭”或受NULL影响行为异常,其实它严格等价于col >= low AND col ,两端都包含。只要lowhigh可比较、类型兼容,且不为NULL,结果就确定。

常见错误现象:

  • 写成WHERE id BETWEEN 10 AND 5——MySQL会自动交换顺序,仍返回5 ,但语义混乱,应避免
  • WHERE date_col BETWEEN '2023-01-01' AND '2023-01-01'查单日数据——它能命中当天00:00:00,但漏掉当天其他时间点(除非date_colDATE类型)
  • TEXTJSON列直接用BETWEEN——可能触发隐式转换或全表扫描,性能差

BETWEEN>=/在索引使用上完全等价

优化器对BETWEEN的处理和显式写col >= a AND col 一样,只要列上有索引,且条件不含函数或表达式,就能走范围扫描(type: range)。

实操建议:

  • 检查执行计划:
    EXPLAIN SELECT * FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31';

    确认key字段非NULLrows量级合理

  • 如果created_atDATETIME,想查2024年1月整月,必须写成BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59',或更安全地用>= '2024-01-01' AND
  • 复合索引中,BETWEEN只能用于最左前缀的连续部分。例如索引(a, b, c)WHERE a = 1 AND b BETWEEN 2 AND 4可用索引,但WHERE a > 1 AND c BETWEEN 10 AND 20无法利用c的索引

字符串和日期用BETWEEN要特别注意排序规则和精度

字符串比较依赖当前列的collation,比如utf8mb4_0900_as_cs区分大小写和重音,而utf8mb4_general_ci不区分。这直接影响BETWEEN 'a' AND 'z'是否包含'Z''é'

AMiner

AMiner

AMiner——新一代智能型科技情报挖掘与服务系统,能够为你提供查找论文、理解论文、分析论文、写作论文四位一体一站式服务。

下载

日期时间类型更要小心:

  • DATE列:直接BETWEEN '2024-01-01' AND '2024-01-01'没问题,精确到日
  • DATETIMETIMESTAMP列:同上写法只匹配00:00:00这一秒,几乎必然为空
  • 时区问题:TIMESTAMP存的是UTC,但BETWEEN字面量按会话时区解析。例如会话在+08:00BETWEEN '2024-01-01' AND '2024-01-01'实际查的是UTC的2023-12-31 16:00:002024-01-01 16:00:00

遇到NULLBETWEEN直接返回UNKNOWN

这是SQL三值逻辑的体现:NULL BETWEEN 1 AND 10既不是TRUE也不是FALSE,而是UNKNOWN,所以该行不会出现在查询结果中——和WHERE子句里所有UNKNOWN都被过滤掉一致。

这意味着:

  • WHERE col BETWEEN 1 AND 10等价于WHERE col >= 1 AND col ,天然排除NULL
  • 如果业务需要包含NULL,必须显式加判断:WHERE (col BETWEEN 1 AND 10) OR col IS NULL
  • 不要依赖BETWEEN来“过滤掉NULL”,它只是顺带不匹配;真正想排除NULL,还是明确写IS NOT NULL更清晰

边界值类型隐式转换、时区上下文、索引生效前提,这三个地方最容易被忽略。写完BETWEEN语句后,务必用EXPLAIN看执行计划,并用SELECT ... LIMIT 5验证实际返回的数据是否符合预期时间/字符范围。

https://www.php.cn/faq/1963815.html

发表回复

Your email address will not be published. Required fields are marked *