推荐用 where create_time >= curdate() and create_time
用
DATE()或CURDATE()获取当天日期直接比较日期字段和当前日期时,别用
NOW()带时间部分的值,否则可能漏掉当天 00:00–23:59 的记录。MySQL 中推荐用CURDATE()(返回YYYY-MM-DD格式),或DATE(NOW())显式截断时间。常见错误是写成
WHERE create_time = NOW()—— 这几乎永远不匹配,因为create_time很少精确到秒级且和NOW()完全一致。
- 正确写法:
WHERE DATE(create_time) = CURDATE()- 更高效写法(能走索引):
WHERE create_time >= CURDATE() AND create_time- 注意:如果
create_time是DATETIME或TIMESTAMP类型,用范围查询比DATE()函数包裹更利于索引利用查最近7天(含今天)用
DATE_SUB()+ 范围查询“最近7天”通常指从今天开始往前推7天(含今天共7天),即
[T-6, T](T 为今天 00:00)。但业务中常理解为“过去7×24小时”,需按需选择逻辑。推荐统一用闭区间左包含、右包含的写法,避免边界遗漏:
- 标准7天(含今天):
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 6 DAY) AND create_time- 过去7×24小时(更严格):
WHERE create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)- PostgreSQL 用户请换用:
WHERE create_time >= CURRENT_DATE - INTERVAL '6 days'- SQLite 用户用:
WHERE create_time >= date('now', '-6 days')不同数据库的时间函数差异要点
同一语义在不同数据库里函数名、参数格式、默认时区行为都不同,硬搬 MySQL 写法到 PostgreSQL 或 SQL Server 会报错或结果偏差。
- MySQL:
CURDATE()、DATE_SUB(CURDATE(), INTERVAL 6 DAY)- PostgreSQL:
CURRENT_DATE、CURRENT_DATE - INTERVAL '6 days'(注意单引号和单位复数)- SQL Server:
GETDATE()配合DATEADD(day, -6, CAST(GETDATE() AS DATE))- Oracle:
TRUNC(SYSDATE)和TRUNC(SYSDATE) - 6(TRUNC去除时间部分)- 关键提醒:所有数据库中,对带时区的字段(如
TIMESTAMP WITH TIME ZONE)做比较前,务必确认时区上下文是否一致,否则WHERE条件可能跨天失效性能陷阱:函数作用于字段会导致索引失效
写
WHERE DATE(create_time) = CURDATE()看似简洁,但DATE()是对字段计算,MySQL 无法使用create_time上的 B-tree 索引,全表扫描风险高。真正要兼顾可读性和性能,优先选范围查询,哪怕多写几个字符:
- ✅ 推荐:
WHERE create_time >= '2024-06-01' AND create_time (预计算好日期字符串,最稳)- ✅ 次选:
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 6 DAY) AND create_time- ❌ 避免:
WHERE DAYOFYEAR(create_time) = DAYOFYEAR(NOW())或其他字段侧函数- 验证方式:执行
EXPLAIN看key列是否非 NULL,rows是否显著小于表总行数实际用的时候,先看字段类型、再定时间语义、最后挑对应数据库的写法——三个变量少一个,结果就可能不对。尤其上线前务必用真实数据量测下
EXPLAIN,别只在空表上试。












