应使用左闭右开区间:>= 起始日 AND = '2024-01-01' AND order_time
查询日期范围时,边界时间遗漏通常是因为用了
BETWEEN或错误的=组合,尤其当字段含时间(DATETIME或TIMESTAMP)时,容易漏掉当天 23:59:59.999 之后的数据。核心原则是:**用左闭右开区间(>= AND )配合精确的结束日+1天**。用 >= 起始日 AND
这是最推荐、最安全的方式,不依赖具体时间精度,也避免时区或毫秒截断问题。
- 查 2024-01-01 到 2024-01-31 全天数据(含 31 日 23:59:59):
SELECT * FROM orders WHERE order_time >= '2024-01-01' AND order_time
注意:
'2024-02-01'是逻辑上的“下一日”,不是手算 31+1;数据库会自动按日期类型对齐到 00:00:00。慎用 BETWEEN —— 它隐含闭区间,易出错
BETWEEN a AND b等价于a 。若b写成'2024-01-31'(无时间部分),多数数据库会补为'2024-01-31 00:00:00',导致漏掉当天所有非零点数据。
- ❌ 错误写法(漏掉 2024-01-31 00:00:01 及之后):
WHERE order_time BETWEEN '2024-01-01' AND '2024-01-31'- ✅ 若坚持用 BETWEEN,必须显式写出时间上限:
WHERE order_time BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59'(仍可能漏毫秒级数据)处理带时区的时间字段
如果字段是
TIMESTAMP WITH TIME ZONE(如 PostgreSQL)或应用层存的是 UTC 时间,务必统一时区再比较。
- 查北京时间 2024-01-01 至 2024-01-31 的数据,且存储为 UTC:
- 先将目标日期转为 UTC 起止时间(例如东八区需减 8 小时):
WHERE order_time >= '2024-01-01 00:00:00+08'::timestamptz AT TIME ZONE 'UTC'
AND order_time索引友好性提醒
使用
>=和的写法能充分利用日期字段上的 B-tree 索引,而函数包裹(如DATE(order_time) = '2024-01-01')会导致全表扫描。
- ✅ 推荐(可走索引):
order_time >= '2024-01-01' AND order_time- ❌ 避免(无法有效利用索引):
DATE(order_time) BETWEEN '2024-01-01' AND '2024-01-31'











