查最近n天数据需动态计算起始日期,mysql推荐date_sub+curdate()/now()组合,postgresql用current_date±interval;注意字段类型、时区统一及边界处理。

查最近 N 天的数据,核心是用当前时间动态推算起始日期,避免硬写死日期。关键是选对函数、注意时区和边界(是否含当天),不同数据库语法略有差异,但逻辑一致。
MySQL:用 DATE_SUB + BETWEEN 最稳妥
推荐组合,语义清晰、性能好、兼容性强:
-
查最近 7 天(含今天):
WHERE create_time BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE()
注意:CURDATE() 返回日期(无时分秒),适合 date/datetime 字段;若字段是 datetime 且需精确到秒,用NOW()替代CURDATE()更严谨。 -
查最近 30 天(不含今天,只到昨天):
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND create_time - 小技巧:INTERVAL 支持 DAY / HOUR / MINUTE / SECOND,可直接查“最近 2 小时”或“最近 5 分钟”。
PostgreSQL:用 CURRENT_DATE 和区间运算
语法更直观,支持日期算术直接加减:
-
最近 7 天(含今天):
WHERE create_time >= CURRENT_DATE - INTERVAL '7 days'
等价于>= CURRENT_DATE - '7 days'::interval,引号和类型转换可省略。 -
要包含今天全部时间(从 00:00:00 到 23:59:59):
用>= (CURRENT_DATE - INTERVAL '6 days')::date和配合 <code>::date截断更安全。 -
生成连续日期序列(如补零统计):
SELECT d::date FROM generate_series(CURRENT_DATE - 6, CURRENT_DATE, '1 day') AS d
通用避坑点:边界、时区与字段类型
很多结果不准,其实卡在这些细节上:
-
datetime 字段 vs date 字段:如果 where 条件用
create_time = '2026-02-25',而字段是 datetime 类型,会漏掉当天所有非 00:00:00 的记录。应改用create_time >= '2026-02-25' AND create_time 或 <code>DATE(create_time) = '2026-02-25'(后者无法走索引)。 -
时区影响:服务器时区、数据库时区、应用层时区不一致时,
NOW()或CURRENT_TIMESTAMP可能和业务预期不符。建议统一用 UTC 存储时间,查询时再按需转换。 -
DATEDIFF 类函数慎用:比如
DATEDIFF(NOW(), create_time) 在某些场景下因四舍五入或跨日计算出错;优先用区间比较,逻辑更可控。
快速验证与调试建议
写完条件别急着跑全表,先确认时间范围是否符合预期:
- 单独执行:
SELECT DATE_SUB(CURDATE(), INTERVAL 7 DAY), CURDATE();(MySQL)或SELECT CURRENT_DATE - INTERVAL '7 days', CURRENT_DATE;(PG) - 加 LIMIT 查几条原始数据:
SELECT create_time FROM table_name ORDER BY create_time DESC LIMIT 5;看最新记录时间戳,比对是否落在你算出的范围内。 - 统计条数对比:
SELECT COUNT(*) FROM table WHERE create_time >= ...和总数据量级是否合理。










