因为between是闭区间,结束时间写'2024-01-01 23:59:59'会遗漏毫秒级数据;正确做法是用左闭右开区间:where dt >= '2024-01-01' and dt
用
BETWEEN查日期时为什么总少最后一秒?因为
BETWEEN是闭区间(包含两端),但你写的结束时间如果是'2024-01-01 23:59:59',就漏掉了'2024-01-01 23:59:59.123'这类带毫秒的记录——尤其在DATETIME或TIMESTAMP类型字段里很常见。正确写法:用开区间替代
BETWEEN处理时间范围把「查 2024-01-01 全天」这种需求,改写成左闭右开:
WHERE dt >= '2024-01-01' AND dt 。这样不管字段精度是秒、毫秒还是微秒,都能覆盖完整一天。
- ✅ 推荐:用
配合「下一个自然边界」,比如查某月就用下月第一天- ❌ 避免硬拼
'23:59:59',MySQL/PostgreSQL/SQL Server 对毫秒处理不一致,Oracle 还可能隐式截断- ⚠️ 注意时区:如果字段是
TIMESTAMP WITH TIME ZONE(如 PostgreSQL),确保比较值也带时区,或统一转为 UTC
BETWEEN不是不能用,但得清楚它对时间类型的“真实含义”当你写
dt BETWEEN '2024-01-01' AND '2024-01-01 23:59:59',数据库实际执行的是:dt >= '2024-01-01 00:00:00' AND dt <p>问题就出在右边这个 <code> —— 它只卡到秒级,而你的数据可能存了 <code>'2024-01-01 23:59:59.999'</code>。</code></p>
- MySQL 5.6+ 的
DATETIME支持微秒,BETWEEN会严格比对全部精度- SQL Server 的
DATETIME2默认精度 7 位,BETWEEN '2024-01-01' AND '2024-01-01 23:59:59'实际等价于- PostgreSQL 中
'2024-01-01'会被隐式转成'2024-01-01 00:00:00',同样存在截断风险特殊情况:必须用
BETWEEN时怎么补救?如果因 ORM 或旧代码约束非用不可,至少让右边界“多留一点余量”:
- 用
DATEADD(SQL Server)或INTERVAL(PostgreSQL/MySQL)把右边界推到下一秒:BETWEEN '2024-01-01' AND '2024-01-01 23:59:59.999'→ 改成BETWEEN '2024-01-01' AND '2024-01-02 00:00:00'(注意这是错的!应改用开区间)- 更稳妥的做法:显式 cast 边界值为同精度类型,例如 PostgreSQL 中写
dt BETWEEN '2024-01-01'::TIMESTAMP AND '2024-01-02'::TIMESTAMP - INTERVAL '1 microsecond'- 但这类写法难读、易错、跨库不兼容——不如一开始就放弃
BETWEEN用于时间范围真正容易被忽略的,是开发时用
SELECT * FROM t WHERE dt BETWEEN ...测试没问题,是因为测试数据全在秒级对齐;上线后遇到带毫秒的真实写入,漏查就静默发生了。











