比较 DATETIME 和 DATE 忽略时间部分

发布于 2024-08-14 01:38:08 字数 138 浏览 10 评论 0原文

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

我必须仅通过日期部分(日+月+年)来比较两个记录,丢弃时间部分(小时+分钟+秒)。

我怎样才能做到这一点?

I have two tables where column [date] is type of DATETIME2(0).

I have to compare two records only by theirs Date parts (day+month+year), discarding Time parts (hours+minutes+seconds).

How can I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

旧城烟雨 2024-08-21 01:38:08

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

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

Use the CAST to the new DATE data type in SQL Server 2008 to compare just the date portion:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
半步萧音过轻尘 2024-08-21 01:38:08

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)

A small drawback in Marc's answer is that both datefields have been typecast, meaning you'll be unable to leverage any indexes.

So, if there is a need to write a query that can benefit from an index on a date field, then the following (rather convoluted) approach is necessary.

  • The indexed datefield (call it DF1) must be untouched by any kind of function.
  • So you have to compare DF1 to the full range of datetime values for the day of DF2.
  • That is from the date-part of DF2, to the date-part of the day after DF2.
  • I.e. (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • NOTE: It is very important that the comparison is >= (equality allowed) to the date of DF2, and (strictly) < the day after DF2. Also the BETWEEN operator doesn't work because it permits equality on both sides.

PS: Another means of extracting the date only (in older versions of SQL Server) is to use a trick of how the date is represented internally.

  • Cast the date as a float.
  • Truncate the fractional part
  • Cast the value back to a datetime
  • I.e. CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
满天都是小星星 2024-08-21 01:38:08

尽管我投票赞成标记为正确的答案。我想为那些偶然发现这一点的人谈谈一些事情。

一般来说,如果您仅专门针对日期值进行过滤。 Microsoft 建议使用语言中性格式 ymdymd

请注意,“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

Though I upvoted the answer marked as correct. I wanted to touch on a few things for anyone stumbling upon this.

In general, if you're filtering specifically on Date values alone. Microsoft recommends using the language neutral format of ymd or y-m-d.

Note that the form '2007-02-12' is considered language-neutral only
for the data types DATE, DATETIME2, and DATETIMEOFFSET.

To do a date comparison using the aforementioned approach is simple. Consider the following, contrived example.

--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

In a perfect world, performing any manipulation to the filtered column should be avoided because this can prevent SQL Server from using indexes efficiently. That said, if the data you're storing is only ever concerned with the date and not time, consider storing as DATETIME with midnight as the time. Because:

When SQL Server converts the literal to the filtered column’s type, it
assumes midnight when a time part isn’t indicated. If you want such a
filter to return all rows from the specified date, you need to ensure
that you store all values with midnight as the time.

Thus, assuming you are only concerned with date, and store your data as such. The above query can be simplified to:

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

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
垂暮老矣 2024-08-21 01:38:08

您可以尝试这个,

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

You can try this one

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

I test that for MS SQL 2014 by following code

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
因为看清所以看轻 2024-08-21 01:38:08

您可以使用 DateDiff 并按天进行比较。

DateDiff(dd,@date1,@date2) > 0

这意味着 @date2 > @date1

例如:

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

结果为:1

You may use DateDiff and compare by day.

DateDiff(dd,@date1,@date2) > 0

It means @date2 > @date1

For example :

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

has the result : 1

你在看孤独的风景 2024-08-21 01:38:08

用于比较两个日期,例如 MM/DD/YYYYMM/DD/YYYY
请记住,字段的第一件事列类型必须是日期时间。
示例:columnName: payment_date dataType:DateTime

之后您可以轻松比较它。
查询是:

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

非常简单......
测试了一下......

For Compare two date like MM/DD/YYYY to MM/DD/YYYY .
Remember First thing column type of Field must be dateTime.
Example : columnName : payment_date dataType : DateTime .

after that you can easily compare it.
Query is :

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

It very simple ......
It tested it.....

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文