如何将日期时间与SQL Server中的日期进行比较

Muh*_*tti 71 sql t-sql sql-server datetime

Select * from [User] U
where  U.DateCreated = '2014-02-07'     
Run Code Online (Sandbox Code Playgroud)

但是在数据库中,用户是2014-02-07 12:30:47.220在我放置时创建的'2014-02-07'

它不显示任何数据

Use*_*ady 74

不要试图做这样的事情:

Select * from [User] U where convert(varchar(10),U.DateCreated, 120) = '2014-02-07'
Run Code Online (Sandbox Code Playgroud)

这是一种更好的方法:

Select * from [User] U 
where U.DateCreated >= '2014-02-07' and U.DateCreated < dateadd(day,1,'2014-02-07')
Run Code Online (Sandbox Code Playgroud)

看:Sargable(该页面已从Wikipedia中删除)

编辑+避免在where子句(或连接条件)中使用数据上的函数有两个基本原因.

  1. 在大多数情况下,使用数据函数来过滤或连接会消除优化器访问该字段上的索引的能力,从而使查询更慢(或更"昂贵")
  2. 另一种是,对于涉及的每行数据,至少执行一次计算.这可能会为查询添加数百,数千或数百万的计算,以便我们可以比较单个条件2014-02-07.改变标准以适应数据的效率要高得多.

"修改适合数据的标准"是我描述"使用SARGABLE谓词"的方式


并且不要在两者之间使用.

日期和时间范围的最佳做法是避免BETWEEN并始终使用表单:

WHERE col> ='20120101'AND col <'20120201'此表单适用于所有类型和所有精度,无论时间部分是否适用.

http://sqlmag.com/t-sql/t-sql-best-practices-part-2(Itzik Ben-Gan)

  • 如果你有一些时间你应该解释为什么一个比另一个更好(索引使用),这将使这个更好的答案 (2认同)
  • 最安全的`date literal`格式是'YYYYMMDD'.数据类型:日期或日期时间或时间或日期时间2或者smalldatetime没有全部格式,因为它们存储为数字.对于日期文字'YYYY-MM-DD'并非完全安全,有一个区域设置可能会将该序列误解为YYYY-DD-MM (2认同)

Ste*_*ord 60

如果您使用的是SQL Server 2008或更高版本,则可以使用date数据类型:

SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2014-02-07'
Run Code Online (Sandbox Code Playgroud)

应该注意的是,如果对日期列进行索引,那么它仍将使用索引并且是SARGable.这是日期和日期时间的特例.

在此输入图像描述

您可以看到SQL Server实际上将其转换为>和<子句:

在此输入图像描述

我刚刚在一个大表上尝试了这个,根据@ kobik的注释在日期列上有一个二级索引,并且仍然使用索引,对于使用BETWEEN或> =和<:的示例不是这种情况.

SELECT *
FROM [User] U
WHERE CAST(U.DateCreated as DATE) = '2016-07-05'
Run Code Online (Sandbox Code Playgroud)

显示二级索引的索引使用情况