正确写法是WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY),因CURDATE()返回日期类型,直接减INTERVAL会丢失时间精度导致多查1天;TIMESTAMP需注意时区转换,DATETIME则无需;应避免BETWEEN,改用左闭右开区间。

查最近7天数据时,CURDATE() 和 INTERVAL 怎么组合才不出错
直接用 CURDATE() - INTERVAL 7 DAY 是常见误区——它会丢掉今天的数据。正确逻辑是「大于等于 7 天前的 00:00:00」,而 CURDATE() 返回的是日期(无时间部分),所以得配合 DATE_SUB() 或显式转成 datetime。
-
CURDATE()返回类似2024-06-15的 DATE 类型,不是2024-06-15 14:23:00 - 写成
WHERE created_at >= CURDATE() - INTERVAL 7 DAY看似合理,但实际等价于>= '2024-06-08',会包含 6 月 8 日全天,共 8 天 - 更安全的写法是:
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY),再补上时间边界:如果字段是DATETIME或TIMESTAMP,建议用WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) + INTERVAL 0 SECOND显式对齐到 00:00:00
created_at 是 TIMESTAMP 还是 DATETIME?影响查询结果是否含今天
两者都支持 INTERVAL 运算,但时区行为不同:TIMESTAMP 存储为 UTC、读取时转本地;DATETIME 原样存储原值。如果你的业务服务器和数据库时区不一致,用 TIMESTAMP 可能导致「本以为查了最近7天,实际少查或多数几个小时」。
- 确认字段类型:
SHOW COLUMNS FROM your_table LIKE 'created_at'; - 若为
TIMESTAMP,且应用写入时没显式指定时区,建议统一在 SQL 中用CONVERT_TZ()对齐,例如:WHERE CONVERT_TZ(created_at, '+00:00', @@session.time_zone) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) - 若为
DATETIME,只要写入时间本身准确,直接用DATE_SUB(CURDATE(), INTERVAL 7 DAY)即可,无需额外转换
为什么用 BETWEEN 查最近7天容易漏数据
BETWEEN '2024-06-08' AND '2024-06-15' 表面看是7天,但实际覆盖的是 6 月 8 日 00:00:00 到 6 月 15 日 23:59:59 —— 如果你的 created_at 是精确到毫秒的 TIMESTAMP(3),最后一条记录可能是 2024-06-15 23:59:59.999,会被包含;但如果数据库时区或客户端时区有偏移,可能被截断或四舍五入。
- 推荐放弃
BETWEEN,改用左闭右开区间:WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND created_at - 这样明确表示「从 7 天前 00:00:00 开始,到明天 00:00:00 之前」,共严格 7×24 小时
- 该写法对索引友好,MySQL 能有效利用
created_at上的 B-tree 索引
测试时发现查不到最新数据?检查 created_at 是否为空或为零值
很多线上表存在历史脏数据:created_at = '0000-00-00 00:00:00' 或 NULL。这类值在比较时会被 MySQL 当作极小值处理,WHERE created_at >= ... 会自动过滤掉它们——看起来像「查不到今天数据」,其实是今天的数据根本没写进去,或者写成了非法时间。
- 快速验证:
SELECT COUNT(*) FROM your_table WHERE created_at IS NULL OR created_at = '0000-00-00 00:00:00'; - 修复建议:建个定时任务清理或修正,或在 INSERT/UPDATE 逻辑里加校验,避免写入非法时间
- 临时绕过(仅调试):
WHERE (created_at IS NOT NULL AND created_at != '0000-00-00 00:00:00') AND created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
真正麻烦的不是语法,而是时间字段的隐式类型转换、时区叠加、以及那些没人记得为什么存在的零值时间。


















