跳转到主要内容
杨月昌的软件博客
返回

SQL Server 日期查询实战:从基础到高级优化技巧

引言

在数据库开发中,日期筛选是最高频的操作之一。虽然 DATEDIFFDATEADD 能解决 90% 的问题,但在处理大数据量时,错误的写法会导致查询效率直线下降。本文不仅分享常用的查询技巧,还将教你如何编写“索引友好”的日期 SQL。


一、 常用时间段筛选(常规写法)

这些语句非常适合报表统计或小规模数据查询。

1. 今天、昨天与过去 N 天

2. 本月与本年


二、 进阶日期计算(精准控制)

3. 获取边界日期(月初、月末)

在旧版本中,我们常用 DATEADD 组合计算,但在 SQL Server 2012 之后,有更优雅的选择:

SELECT DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0);
SELECT EOMONTH(GETDATE()); -- SQL Server 2012+ 支持
SELECT DAY(EOMONTH(GETDATE()));

4. 计算周一(不受特定语言设置影响)

直接使用 DATEDIFF 计算基准日期(0 代表 1900-01-01,那是周一)的差值:

SELECT DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) AS ThisMonday;

三、 性能优化:编写索引友好的查询 (SARG)

这是本文最重要的部分。 > 警惕:当你写 WHERE DATEDIFF(dd, CreateTime, GETDATE()) = 0 时,SQL Server 必须对表中每一行执行函数计算,这会导致索引失效(Index Scan)。

优化方案:计算范围,而不是计算字段。

如果你想查询今天的数据,推荐写法:

-- 这种写法支持索引寻址 (Index Seek)
DECLARE @Today DATE = GETDATE();
SELECT * FROM 表名 
WHERE CreateTime >= CAST(@Today AS DATETIME) 
  AND CreateTime < CAST(DATEADD(dd, 1, @Today) AS DATETIME);

四、 常用函数速查表

函数说明示例
GETDATE()获取当前系统时间2024-01-14 14:30:00
DATEPART(dw, dt)返回周几(数字)1 (周日) 或 2 (周一)
DATENAME(month, dt)返回月份名称January一月
CONVERT(varchar, dt, 23)格式化日期2024-01-14 (ISO 格式)

五、 常见问题 FAQ


总结

掌握日期函数只是第一步,意识到函数对索引的影响才是进阶资深开发者的关键。在处理百万级以上的数据表时,请务必使用 Range Query(范围查询)代替字段上的 DATEDIFF



上一篇
归一化技术全景:从数据预处理到现代大模型的稳定器
下一篇
Python 算法实战:从初级到骨灰级的素数判定函数