如何在SQL Server中查询上个月的所有记录
SQL Server 查询[Sales]表上月全部记录的解决方案
直接给出可在所有SQL Server版本运行的高性能查询语句:
SELECT * FROM [Sales] WHERE SoldDate >= DATEADD(month, DATEDIFF(month, 0, GETDATE()) - 1, 0) AND SoldDate < DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
逻辑说明
- 核心采用左闭右开的时间区间判断,完美覆盖上月从1号0点到当月1号0点前的所有记录,包括上月最后一天23:59:59.999的时间点,不会出现时间遗漏。
- 两个时间节点的计算逻辑:
DATEDIFF(month, 0, GETDATE()):计算当前日期和SQL Server基准日期(1900-01-01)的月份差- 月份差减1后加回基准日期,得到上个月1号的0点
- 月份差直接加回基准日期,得到本月1号的0点
方案优势
- 没有对
SoldDate字段做任何函数运算,可以正常命中该字段上的索引,大数据量下查询性能远高于对字段做年月截取对比的写法。 - 自动适配大小月、闰月、跨年场景,不需要手动判断当月天数,也不需要额外处理时间精度问题。
如果使用的是SQL Server 2022及更高版本,可以用新增的DATETRUNC函数简化写法:
SELECT * FROM [Sales] WHERE SoldDate >= DATETRUNC(month, DATEADD(month, -1, GETDATE())) AND SoldDate < DATETRUNC(month, GETDATE())
避坑提醒
不要使用以下存在缺陷的写法:
-- 错误写法1:1月查询时跨年逻辑失效,且无法命中SoldDate索引 SELECT * FROM [Sales] WHERE YEAR(SoldDate) = YEAR(GETDATE()) AND MONTH(SoldDate) = MONTH(GETDATE()) - 1 -- 错误写法2:datetime类型精度为3ms,会遗漏上月最后一天23:59:59.997到23:59:59.999的记录 SELECT * FROM [Sales] WHERE SoldDate BETWEEN '上月1号' AND '上月最后一天 23:59:59.999'
内容的提问来源于stack exchange,提问作者tigra13
相关产品推荐
相关产品推荐

