比较DATETIME和DATE忽略时间部分

aba*_*hev 140 sql t-sql sql-server sql-server-2008 datetime-conversion

我有两个表,其中列[date]是类型DATETIME2(0).

我必须比较他们日期部分(日+月+年)的两个记录,丢弃时间部分(小时+分钟+秒).

我怎样才能做到这一点?

mar*_*c_s 238

使用SQL Server 2008中CAST的新DATE数据类型仅比较日期部分:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
Run Code Online (Sandbox Code Playgroud)


Dis*_*ned 60

Marc的答案中的一个小缺点是两个日期字段都被强制转换,这意味着您将无法利用任何索引.

因此,如果需要编写可以从日期字段上的索引中受益的查询,则需要以下(相当复杂的)方法.

  • 索引的日期字段(称为DF1)必须不受任何类型的函数的影响.
  • 因此,您必须将DF1与DF2当天的全部日期时间值进行比较.
  • 这是从DF2的日期部分到DF2之后的日期部分.
  • (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • 注意:比较是> =(允许相等)到DF2的日期,(严格地说)< DF2之后的日期非常重要.BETWEEN运算符也不起作用,因为它允许双方相等.

PS:另一种仅提取日期的方法(在旧版本的SQL Server中)是使用如何在内部表示日期的技巧.

  • 将日期转换为浮点数.
  • 截断小数部分
  • 将值转换回日期时间
  • CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)


rez*_*e08 7

你可以试试这个

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')
Run Code Online (Sandbox Code Playgroud)

我通过以下代码测试了 MS SQL 2014

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
Run Code Online (Sandbox Code Playgroud)


rob*_*pim 5

虽然我赞成标记为正确的答案。我想为任何遇到此问题的人谈一些事情。

通常,如果您仅针对日期值进行专门过滤。微软建议使用的语言无关的格式ymdy-m-d

请注意,表单“2007-02-12”仅对于数据类型 DATE、DATETIME2 和 DATETIMEOFFSET 被视为与语言无关。

使用上述方法进行日期比较很简单。考虑以下人为设计的示例。

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate
Run Code Online (Sandbox Code Playgroud)

在理想情况下,应该避免对过滤列执行任何操作,因为这会阻止 SQL Server 有效地使用索引。也就是说,如果您存储的数据只涉及日期而不是时间,请考虑DATETIME以午夜作为时间进行存储。因为:

当 SQL Server 将文字转换为筛选列的类型时,如果未指示时间部分,则假定为午夜。如果您希望这样的过滤器返回指定日期的所有行,您需要确保以午夜为时间存储所有值。

因此,假设您只关心日期,并按原样存储您的数据。上面的查询可以简化为:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
Run Code Online (Sandbox Code Playgroud)