最直接方式是where orderdate >= dateadd(day, -7, getdate()),可筛选最近7天含今天的数据;若需从今天00:00:00起算,则用dateadd(day, -7, cast(getdate() as date))。

WHERE 条件里用 DATEADD(DAY, -7, GETDATE()) 是最直接的方式
不需要变量、不依赖临时表,一条 WHERE 就能筛出最近 7 天(含今天)的数据。核心是把 GETDATE() 当基准,用 DATEADD() 往前推 7 天,再和日期字段做 >= 比较。
常见错误现象:
-
WHERE DateColumn = DATEADD(DAY, -7, GETDATE())—— 这只查「恰好是 7 天前那一秒」的数据,基本查不到东西 WHERE DATEDIFF(DAY, DateColumn, GETDATE()) —— 表面看逻辑对,但会导致索引失效,大数据量时明显变慢
正确写法示例:
SELECT * FROM Orders WHERE OrderDate >= DATEADD(DAY, -7, GETDATE());
注意:这个条件会包含今天 00:00:00.000 到当前执行时刻之间的所有记录。如果业务要求「严格从今天零点起算」,得手动截断时间部分。
需要精确到「今天 00:00:00」起点?用 CAST(GETDATE() AS DATE) 配合 DATEADD
当表里日期字段是 datetime 或 datetime2 类型,而你想让范围从「今天凌晨开始」而非「此刻往前推 7 天」,直接用 GETDATE() 会漏掉今天早些时候的记录(比如查询在下午执行,就查不到今天上午的数据)。
解决办法是先归一化到日期边界:
-
CAST(GETDATE() AS DATE)得到今天日期(如2026-04-21) - 再用
DATEADD(DAY, -7, CAST(GETDATE() AS DATE))算出 7 天前的 00:00:00
完整 WHERE 条件:
WHERE OrderDate >= DATEADD(DAY, -7, CAST(GETDATE() AS DATE)) AND OrderDate <p>这样能确保覆盖「过去 7 个完整日 + 今天全天」,且两端都是确定的时间点,利于索引使用。</p><h3> <code>GETDATE()</code> 和 <code>SYSDATETIME()</code> 的选择影响精度和兼容性</h3><p>两者都返回当前时间,但细节差别会影响结果:</p>
-
GETDATE()返回datetime,精度约 3.33 毫秒,SQL Server 2005+ 全支持 -
SYSDATETIME()返回datetime2(7),精度达 100 纳秒,但 SQL Server 2008+ 才有
日常查 7 天数据,用 GETDATE() 完全够用;如果表字段是 datetime2 且你在意微秒级一致性(比如做跨系统时间比对),可换 SYSDATETIME(),但要注意旧版本不兼容。
别混用:比如 DATEADD(DAY, -7, SYSDATETIME()) 和 datetime 字段比较,SQL Server 会隐式转换,虽能运行,但可能触发意外的类型推导或警告。
性能关键:确保日期字段上有索引,且 WHERE 写法不破坏索引可用性
哪怕语句逻辑完全正确,如果写法让优化器无法走索引,查百万行就会卡住。
必须避开这些写法:
WHERE DATEDIFF(DAY, OrderDate, GETDATE()) —— 函数作用于字段,索引失效-
WHERE CONVERT(VARCHAR, OrderDate, 112) >= '20260414'—— 同样,字段被函数包裹 -
WHERE OrderDate BETWEEN DATEADD(...) AND GETDATE()—— 看似合理,但右边界是动态的,统计信息难预估,有时不如单纯 >= 左边界稳定
推荐组合:
- 字段类型为
datetime或datetime2 - 在该字段上建非聚集索引:
CREATE INDEX IX_Orders_OrderDate ON Orders(OrderDate); - WHERE 条件保持字段裸露:
OrderDate >= DATEADD(...)
最后提醒一句:DATEADD(DAY, -7, GETDATE()) 在每次查询中都会重新计算,不是常量。如果同一个查询里多次用到,又怕重复计算开销,才考虑用变量缓存——但绝大多数场景下没必要。










