SQL 中 BETWEEN 的边界陷阱
发布时间 - 2026-01-24 00:00:00 点击率:次SQL BETWEEN 是闭区间,但易被误读为半开区间;数字字段勿加引号;NULL 值致整个条件为 UNKNOWN 而被过滤;边界或字段为 NULL 时需用 COALESCE 或拆分为显式比较。
SQL BETWEEN 是闭区间,但容易被误读为半开区间
很多人写 BETWEEN 时下意识觉得它像编程语言里的 for (i = start; i ,其实不是:BETWEEN a AND b 等价于 column >= a AND column ,两端都包含。问题常出在时间字段上——比如想查“2025-01-01 当天的数据”,写成 WHERE dt BETWEEN '2025-01-01' AND '2025-01-01',看似合理,但若 dt 是 DATETIME 或 TIMESTAMP 类型,实际只命中 '2025-01-01 00:00:00' 这一秒。
- 日期型字段(如
DATE)用BETWEEN '2025-01-01' AND '2025-01-01'是安全的 - 时间型字段(
D/
ATETIME
TIMESTAMP)必须显式指定右边界上限,例如'2025-01-01 23:59:59'或更稳妥的'2025-01-02' - INTERVAL 1 SECOND - 使用
CAST('2025-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 的行,UNKNOWN 和 FALSE 一样被过滤掉。
-
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 >= '2025-01-01' AND dt 比BETWEEN '2025-01-01' AND '2025-01-01 23:59:59'更简洁、无秒级精度焦虑、兼容所有时间类型 - 带参数的查询中,用两个独立参数
@start和@end,配合col >= @start AND col ,能天然规避NULL边界问题(只要参数未传,就跳过对应条件) - 某些 ORM(如 SQLAlchemy)生成的 SQL 会避免
BETWEEN,优先用拆开的比较,正是出于可预测性和调试友好性考虑
边界到底包不包含,从来不是语法问题,而是你对数据类型、存储精度和业务语义的理解是否到位。写完 BETWEEN 后,花十秒想想字段的实际值长什么样,比背规则有用得多。
# 编程语言
# sql
# 数据类型
# NULL
# for
# select
# 字符串
# column
# 数据库
# 误读
# 的是
# 是一个
# 半开
# 也会
# 隐式
# 很多人
# 你想
# 得多
# 会让
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
网站制作免费,什么网站能看正片电影?
轻松掌握MySQL函数中的last_insert_id()
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
zabbix利用python脚本发送报警邮件的方法
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
如何快速查询网站的真实建站时间?
无锡营销型网站制作公司,无锡网选车牌流程?
Laravel如何与Inertia.js和Vue/React构建现代单页应用
Python并发异常传播_错误处理解析【教程】
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
微信小程序 wx.uploadFile无法上传解决办法
网站制作企业,网站的banner和导航栏是指什么?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
如何在阿里云服务器自主搭建网站?
七夕网站制作视频,七夕大促活动怎么报名?
Laravel如何实现事件和监听器?(Event & Listener实战)
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Laravel如何实现多对多模型关联?(Eloquent教程)
Laravel怎么调用外部API_Laravel Http Client客户端使用
如何在搬瓦工VPS快速搭建网站?
如何在建站主机中优化服务器配置?
如何为不同团队 ID 动态生成多个“认领值班”按钮
如何在云主机快速搭建网站站点?
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
Android仿QQ列表左滑删除操作
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
C++用Dijkstra(迪杰斯特拉)算法求最短路径
如何快速搭建安全的FTP站点?
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
如何用AWS免费套餐快速搭建高效网站?
Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能
JavaScript常见的五种数组去重的方式
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
javascript中对象的定义、使用以及对象和原型链操作小结
网站制作软件有哪些,制图软件有哪些?
晋江文学城电脑版官网 晋江文学城网页版直接进入
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
如何快速完成中国万网建站详细流程?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
如何快速搭建高效WAP手机网站?
JavaScript如何实现错误处理_try...catch如何捕获异常?
黑客如何通过漏洞一步步攻陷网站服务器?
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
微信公众帐号开发教程之图文消息全攻略
上一篇:git怎么丢弃还没add的文件
下一篇:ubuntu上在哪配置git
上一篇:git怎么丢弃还没add的文件
下一篇:ubuntu上在哪配置git


