正确写法是where created_at >= date_sub(now(), interval 30 day),因字段为datetime类型需保留时分秒,用now()确保精度;curdate()仅适用于date类型字段。

MySQL 中用 DATE_SUB() 计算近7天或近30天
MySQL 没有直接的“近N天”语法,得靠 DATE_SUB() 或 DATE_ADD() 配合 CURDATE() 或 NOW() 构造时间范围。关键看字段类型和是否含时分秒:
- 如果业务时间字段是
DATE类型(如order_date),用CURDATE()更干净; - 如果是
DATETIME或TIMESTAMP(如created_at),推荐用NOW(),避免漏掉当天最后几秒的数据。
常见错误是写成 WHERE created_at >= NOW() - INTERVAL 7 DAY —— 看似没问题,但若字段带时区或索引没覆盖到秒级,可能丢数据或不走索引。
-- ✅ 推荐:显式范围,利于索引使用 SELECT * FROM orders WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) AND created_at -- ❌ 不推荐:NOW() - INTERVAL 7 DAY 在某些旧版本 MySQL 中可能隐式截断 -- 且 <code>NOW() - INTERVAL 7 DAY</code> 是表达式,无法利用函数索引(除非建了函数索引)
PostgreSQL 中用 CURRENT_DATE 和 INTERVAL
PostgreSQL 时间计算更直观,CURRENT_DATE 返回日期部分,NOW() 返回带时分秒的时间戳。选哪个取决于字段类型和是否要包含今天尚未发生的时刻。
- 字段是
DATE:用CURRENT_DATE - INTERVAL '7 days'; - 字段是
TIMESTAMP WITH TIME ZONE:用NOW() - INTERVAL '7 days',但注意时区偏移可能影响结果。
容易踩的坑是忘记 INTERVAL 后面的单引号,比如写成 INTERVAL 7 days 会报错 syntax error at or near "7"。
-- ✅ 正确写法(含引号、单位小写) SELECT * FROM logs WHERE event_time >= CURRENT_DATE - INTERVAL '30 days'; <p>-- ✅ 若需精确到秒,用 NOW() SELECT * FROM logs WHERE event_time >= NOW() - INTERVAL '7 days';</p>
SQL Server 中用 DATEADD() 和 GETDATE()
SQL Server 不支持 INTERVAL 语法,必须用 DATEADD()。参数顺序固定:单位、数值、基准时间。单位不能缩写为 d 或 dd,必须是 day(SQL Server 2005+ 支持)或 dd(兼容旧版),但统一用 day 更安全。
另一个易错点是误用 GETDATE() - 7 —— 这在 SQL Server 中会被当作“减去7天的日期”,但本质是隐式转换为数字相减,可读性差,且在某些设置下可能出错。
-- ✅ 推荐:语义清晰,兼容性好 SELECT * FROM sales WHERE order_time >= DATEADD(day, -7, GETDATE()); <p>-- ✅ 查近30天(注意:>= 起点,不含未来时间) SELECT * FROM sales WHERE order_time >= DATEADD(day, -30, GETDATE()) AND order_time </p>
通用注意事项:索引、时区与字段精度
时间范围查询性能高度依赖索引。如果经常查 created_at,确保该字段有单列索引或作为联合索引最左前缀。否则即使 SQL 写对了,也会全表扫描。
时区问题常被忽略:
- 应用写入用的是 UTC,但数据库服务器时区设为
Asia/Shanghai,NOW()就比实际晚8小时; - 解决办法是统一用 UTC 函数(如 MySQL 的
UTC_TIMESTAMP(),PostgreSQL 的NOW() AT TIME ZONE 'UTC'),或在应用层做归一化。
还有字段精度陷阱:
-
DATETIME(3)(毫秒)和DATETIME(秒)在比较时可能因隐式截断导致边界数据丢失; - 建议统一用
DATETIME(3)或TIMESTAMP,并在查询中保持精度一致。
真正难的不是写出“近7天”的 SQL,而是让这条 SQL 在百万级表上稳定跑进 100ms,且不因时区、索引缺失或字段类型变化突然变慢。











