在 SQL Server 中,与固定日期进行比较的写法-SQL Server服务中心-电脑网络-本牛千智丨专注WorkFine开发

在 SQL Server 中,与固定日期进行比较的写法

先看为快

-- 查找 2023-10-01 当天的所有数据
WHERE OrderDate >= '20231001' 
  AND OrderDate < '20231002';

在 SQL Server 中,与固定日期进行比较时,核心原则是使用标准的日期格式字符串日期字面量,以确保查询能够正确利用索引(SARGable)并避免隐式转换带来的性能问题或错误。

以下是几种推荐的写法及注意事项:

1. 推荐写法:使用 ISO 8601 格式字符串

这是最安全、最通用的方法,不受服务器语言设置(Language Settings)的影响。

  • 格式 YYYYMMDD (无分隔符):适用于纯日期比较。-- 比较 2023年10月1日 WHERE OrderDate >= '20231001' AND OrderDate < '20231002';
  • 格式 YYYY-MM-DDThh:mm:ss (带 T 分隔符):适用于包含时间的 datetime/datetime2 类型。-- 比较 2023年10月1日 下午2点30分 WHERE CreatedAt >= '2023-10-01T14:30:00';

2. 使用 DATEDATETIME2 字面量 (SQL Server 2008+)

如果你明确知道列的数据类型,可以直接使用类型前缀,这样代码可读性更高且类型安全。

-- 显式转换为 DATE 类型
WHERE OrderDate >= CAST('2023-10-01' AS DATE)

-- 或者直接使用日期字面量 (SQL Server 会隐式处理,但显式更好)
WHERE OrderDate >= '2023-10-01' -- 如果列是 DATE 类型,这通常也是安全的

3. 常见场景示例

场景 A:查找特定日期的所有记录(注意时间部分)

如果列类型是 DATETIMEDATETIME2,它包含时间部分。直接等于某个日期字符串通常查不到数据(除非时间恰好是 00:00:00)。 错误写法WHERE OrderDate = '2023-10-01' (只会匹配 2023-10-01 00:00:00.000)

正确写法(范围查询)

-- 查找 2023-10-01 当天的所有数据
WHERE OrderDate >= '20231001' 
  AND OrderDate < '20231002';

这种写法可以利用索引,效率最高。

替代写法(使用 CAST,可能无法利用索引)

-- 将列转换为日期进行比较 (会导致索引失效,大数据量表不推荐)
WHERE CAST(OrderDate AS DATE) = '2023-10-01';

场景 B:查找早于或晚于某日期的记录

-- 查找 2023年1月1日 之前的记录
WHERE ExpiryDate < '20230101';

-- 查找 2023年1月1日 之后的记录(包含当天)
WHERE StartDate >= '20230101';

4. 需要避免的写法

  • 避免使用区域性格式:如 '01/10/2023''10-01-2023'
    • 如果服务器语言设置为 us_english (mdy),'01/10/2023' 会被解析为 1月10日。
    • 如果服务器语言设置为 British (dmy),'01/10/2023' 会被解析为 10月1日。
    • 这会导致代码在不同服务器上行为不一致。
  • 避免在列上进行函数运算(除非万不得已):
    • 不要写 WHERE YEAR(OrderDate) = 2023 AND MONTH(OrderDate) = 10,这会导致全表扫描。请改用范围查询 >= '20231001' AND < '20231101'

总结最佳实践代码

SELECT *
FROM Orders
WHERE 
    -- 推荐使用 YYYYMMDD 格式进行日期范围过滤
    OrderDate >= '20231001' 
    AND OrderDate < '20231002'
    
    -- 如果需要精确到时间点,使用 ISO 8601 (带 T)
    AND CreatedAt >= '2023-10-01T09:00:00';

这种方式既保证了准确性(不受语言设置影响),又保证了性能(可以使用索引)。

请登录后发表评论

    请登录后查看回复内容