0

0

SQL 中 BETWEEN 的边界陷阱

冰川箭仙

冰川箭仙

发布时间:2026-01-24 16:30:11

|

798人浏览过

|

来源于php中文网

原创

SQL BETWEEN 是闭区间,但易被误读为半开区间;数字字段勿加引号;NULL 值致整个条件为 UNKNOWN 而被过滤;边界或字段为 NULL 时需用 COALESCE 或拆分为显式比较。

sql 中 between 的边界陷阱

SQL BETWEEN 是闭区间,但容易被误读为半开区间

很多人写 BETWEEN 时下意识觉得它像编程语言里的 for (i = start; i ,其实不是:BETWEEN a AND b 等价于 column >= a AND column ,两端都包含。问题常出在时间字段上——比如想查“2024-01-01 当天的数据”,写成 WHERE dt BETWEEN '2024-01-01' AND '2024-01-01',看似合理,但若 dtDATETIMETIMESTAMP 类型,实际只命中 '2024-01-01 00:00:00' 这一秒。

  • 日期型字段(如 DATE)用 BETWEEN '2024-01-01' AND '2024-01-01' 是安全的
  • 时间型字段(DATETIME/TIMESTAMP)必须显式指定右边界上限,例如 '2024-01-01 23:59:59' 或更稳妥的 '2024-01-02' - INTERVAL 1 SECOND
  • 使用 CAST('2024-01-01' AS DATE) 强制截断时间部分,再配合范围比较,比依赖 BETWEEN 更可控

字符串和数字的 BETWEEN 行为一致,但隐式类型转换会埋雷

BETWEEN 对字符串、数字、日期都按各自类型的自然序比较,不自动转类型。陷阱在于:如果字段是字符串类型(如 VARCHAR),而你传入数字字面量,数据库可能触发隐式转换——MySQL 会把字符串转成数字比较,PostgreSQL 则直接报错。

  • 字段为 code VARCHAR(10),存的是 '001', '010', '100',执行 WHERE code BETWEEN 1 AND 100 在 MySQL 中会变成数值比较,结果返回全部三行;但语义上你本意可能是字符串字典序
  • 正确做法是统一用字符串字面量:WHERE code BETWEEN '001' AND '100',此时按字典序比较,'010' 会被包含,'001' 也会,但 '2' 就不会(因为 '2' > '100'
  • 数字字段别用引号:id BETWEEN '1' AND '10' 在某些数据库里会触发字符串转数字,但不如直接写 id BETWEEN 1 AND 10 明确且免去转换开销

NULL 值会让 BETWEEN 整个条件失效

BETWEEN 是一个组合布尔表达式,只要任一操作数为 NULL(比如字段值为 NULL,或边界值来自子查询返回 NULL),整个表达式结果就是 UNKNOWN,而 WHERE 只接受 TRUE 的行,UNKNOWNFALSE 一样被过滤掉。

Sologo AI
Sologo AI

SologoAI 是一款AI在线LOGO生成工具,帮助用户快速创建独特且专业的品牌标识和配套VI设计。

下载
  • SELECT * FROM orders WHERE amount BETWEEN 100 AND NULL —— 永远不返回任何行,哪怕表里有数据
  • 边界来自参数或变量时,务必先判断是否为 NULL,例如用 COALESCE(@min, 0) 或拆成独立条件:amount >= @min AND @min IS NOT NULL
  • 字段本身允许 NULL 且你想包含这些行?不能靠 BETWEEN,得额外用 OR amount IS NULL

替代方案往往比 BETWEEN 更清晰、更可控

多数时候,显式写出 >=(或 )反而更不容易出错,尤其涉及时间、可空字段或动态边界时。

  • 查某天全量数据:dt >= '2024-01-01' AND dt 比 BETWEEN '2024-01-01' AND '2024-01-01 23:59:59' 更简洁、无秒级精度焦虑、兼容所有时间类型
  • 带参数的查询中,用两个独立参数 @start@end,配合 col >= @start AND col ,能天然规避 NULL 边界问题(只要参数未传,就跳过对应条件)
  • 某些 ORM(如 SQLAlchemy)生成的 SQL 会避免 BETWEEN,优先用拆开的比较,正是出于可预测性和调试友好性考虑

边界到底包不包含,从来不是语法问题,而是你对数据类型、存储精度和业务语义的理解是否到位。写完 BETWEEN 后,花十秒想想字段的实际值长什么样,比背规则有用得多。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

686

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

324

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1137

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

359

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

737

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

577

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

420

2024.04.29

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 19万人学习

Rust 教程
Rust 教程

共28课时 | 4.8万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号