比较DATETIME和DATE,忽略时间部分

175

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

我需要仅通过它们的日期部分(日+月+年),而不考虑时间部分(小时+分钟+秒)来比较两个记录。

我该如何做到这一点?

6个回答

297

在SQL Server 2008中使用CAST将数据类型转换为新的DATE数据类型,以仅比较日期部分:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)

64

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)

7
虽然我点赞了被标记为正确的答案,但我想就一些事情提供一些建议,以供那些碰巧看到这个帖子的人参考。
通常情况下,如果你只是在特定于日期的值上进行过滤。 Microsoft 建议使用语言中立格式 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

在理想情况下,应避免对过滤列执行任何操作,因为这可能会阻止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

6
你可以尝试这个。
CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

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

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

4
您可以使用DateDiff并按天进行比较。
DateDiff(dd,@date1,@date2) > 0

这意味着 @date2 > @date1

例如:

select DateDiff(dd, '01/01/2021 10:20:00', '02/01/2021 10:20:00') 

结果为:1


-3

如何比较两个日期,格式为MM/DD/YYYYMM/DD/YYYY。 首先,字段的列类型必须是dateTime。 例如:columnName:payment_date dataType:DateTime

之后,您可以轻松地进行比较。 查询语句为:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

这很简单...... 我测试过了.....


这并没有完全回答问题。它查询的是一个月,而不是一天。 - Curtis Yallop
此答案未涉及问题中要求的2个表。 - Curtis Yallop
是的,我同意,但我只是提供了一种解决方案,而不是国际解决方案...你需要更改一些顺序... - pankaj
问题仅为“在SQL Server 2008中仅按日期而非时间比较两个DATETIME”。 - pankaj
  1. 你的答案没有比较两个日期时间值,而是将一个值与两个常量进行比较。
  2. 你的答案未能满足忽略比较时的时间部分的要求。
  3. 你声称“字段必须是日期时间”是完全错误的。
- Disillusioned
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接