一 说明
1.1 总结
1)字段是date类型,放心用between....and
2)字段时datetime/timestamp,最好别用between 日期 and 日期
统一用:>=开始日期 and < 结束日期+1 天
1.2 汇总
|-----------------------------------|----------------------------------------------------------------|--------------------------------------------------------------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
| 字段类型 | 写法 | 实际范围 | 统计结果 | 坑点 |
| Date(仅日期) | BETWEEN '2026-04-12' AND '2026-04-13' | >= '2026-04-12' AND <= '2026-04-13' | 完整 2 天 | 无坑,正常 |
| Date类型 | create_time>='2024-04-13' and create_time<'2026-04-16' | create_time >= '2024-04-13 00:00:00' AND create_time < '2026-04-16 00:00:00' | [2024-04-13, 2026-04-15] | |
| Date类型 | create_time>='2024-04-13' and create_time<='2026-04-16' | create_time >= '2024-04-13 00:00:00' AND create_time <='2026-04-16 23:59:59' | date <= '2026-04-16'等价于覆盖当天一整天 date < '2026-04-16'等价于不包含 16 号,只到 15 号 | |
| datetime / timestamp(带时间) | BETWEEN '2026-04-12' AND '2026-04-13' | >= '2026-04-12 00:00:00' AND <= '2026-04-13 00:00:00' | 1 天多 1 秒只到 13 日 0 点 | 严重漏数据13 日白天数据全丢 |
| datetime / timestamp | >= '2026-04-12' AND < '2026-04-14' | [2026-04-12 00:00:00, 2026-04-14 00:00:00) | 2026-04-12, 2026-04-13 这 完整 2 天 | 最推荐,无任何坑 |
| datetime / timestamp | BETWEEN '2026-04-12 00:00:00' AND '2026-04-13 23:59:59' | 完整两天 | 完整 2 天 | 毫秒 / 微秒数据仍可能漏 |
| datetime / timestamp | create_time<'2025-04-14' | create_time < '2025-04-14 00:00:00' | 小于 2025-04-14 零点 最多查到 2025-04-13 23:59:59.999 | 包含 :所有 2025-04-13 23:59:59 及之前的所有时间 不包含 :2025-04-14 00:00:00 及之后的任何时间 |
| Varchar | request_time >= '2026-04-13' AND request_time < '2026-04-15' | 2026-04-13 00:00:00 ~ 2026-04-14 23:59:59 | | |
把时间存成 varchar,相当于给数据库埋雷:查询会错、占用空间更大,浪费内存,索引会废、函数不能用、脏数据控制不住、后期改不动。
- 比较、范围查询、排序 100% 可能出错
- 索引会失效,查询巨慢
- 无法使用日期函数
- 无法阻止脏数据
- 空间浪费、性能差、维护难
二 案例分析
2.1 案例
1脚本
DROP TABLE IF EXISTS `tb_test_seek_date`;
CREATE TABLE `tb_test_seek_date` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`order_date` date NULL DEFAULT NULL COMMENT '订单日期',
`consume_time` datetime(0) NULL DEFAULT NULL COMMENT '消费时间',
`create_time` timestamp(0) NULL DEFAULT NULL COMMENT '入库时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_test_seek_date
-- ----------------------------
INSERT INTO `tb_test_seek_date` VALUES (1, '2026-04-10', '2026-04-10 20:12:12', '2026-04-10 21:12:12');
INSERT INTO `tb_test_seek_date` VALUES (2, '2026-04-11', '2026-04-11 20:12:12', '2026-04-11 21:12:12');
INSERT INTO `tb_test_seek_date` VALUES (3, '2026-04-12', '2026-04-12 20:12:12', '2026-04-12 21:12:12');
INSERT INTO `tb_test_seek_date` VALUES (4, '2026-04-13', '2026-04-13 20:12:12', '2026-04-13 21:12:12');
INSERT INTO `tb_test_seek_date` VALUES (5, '2026-04-11', '2026-04-11 00:00:00', '2026-04-11 00:00:00');
INSERT INTO `tb_test_seek_date` VALUES (6, '2026-04-11', '2026-04-11 00:00:01', '2026-04-11 00:00:01');
INSERT INTO `tb_test_seek_date` VALUES (7, '2026-04-11', '2026-04-11 23:59:59', '2026-04-11 23:23:59');
INSERT INTO `tb_test_seek_date` VALUES (8, '2026-04-12', '2026-04-12 00:00:00', '2026-04-12 00:00:00');
SET FOREIGN_KEY_CHECKS = 1;
2.分析全部数据
select * from tb_test_seek_date

2.order_date字段是date类型,使用between and 查询完整两天

- consume_time为datetime类型,使用between and
select * from tb_test_seek_date where consume_time between '2026-04-10' and '2026-04-11' ;
查询就是
|---------------------------------------------------|
| >=2026-04-10 00:00:00 and <=2026-04-11 00:00:00 |
即: 1 天多 1 秒只到 11 日 0 点

- create_time为timestamp类型,使用between and
select * from tb_test_seek_date where create_time between '2026-04-10' and '2026-04-11'
查询就是
|---------------------------------------------------|
| >=2026-04-10 00:00:00 and <=2026-04-11 00:00:00 |
即: 1 天多 1 秒只到 11 日 0 点

5.使用范围:实际为【2026-04-10 00:00:00 到2026-04-11 23:59:59】
select * from tb_test_seek_date where create_time >='2026-04-10' and create_time<'2026-04-12'

6.使用between and 加上时间:实际为【2026-04-10 00:00:00 到2026-04-11 23:59:59】
select * from tb_test_seek_date where create_time between '2026-04-10 00:00:00' and '2026-04-11 23:59:59'
