【问题标题】:Get row where datetime column = today - SQL server noob获取日期时间列 = 今天的行 - SQL Server noob
【发布时间】:2010-04-06 07:14:29
【问题描述】:

在 sql 2005 中,不是从 dateparts 年、月和日期构建查询,

有没有更简洁的方式来编写 where 子句?

【问题讨论】:

  • 我想知道是否有任何答案比这更简洁。我也觉得这更具可读性。其中 (DATEPART(yy, myColum) = '2010') AND (DATEPART(mm, myColum) = '4') AND (DATEPART(dd, myColum) = '7');
  • @Chin,您的方法会阻止索引的使用,并且会导致缓慢的表扫描。我强烈建议您不要使用该方法基于日期进行搜索。如果要使用索引,则需要对范围内的日期进行“下限”,并且不对列应用任何函数。这是如何确定日期时间:stackoverflow.com/questions/85373/floor-a-date-in-sql-server
  • @KM,谢谢。我想我会问一下,看看我是否离开了基地。目前我不知道此列上有索引。不过,我会记住这一点,并按照您的建议确定我的日期。

标签: sql-server sql-server-2005


【解决方案1】:

在 SQL Server 2008 上,您将拥有一个新的 DATE 数据类型,您可以使用它来实现此目的:

SELECT (list of fields)
FROM dbo.YourTable
WHERE dateValue BETWEEN 
   CAST(GETDATE() AS DATE) AND DATEADD(DAY, 1, CAST(GETDATE() AS DATE))

CAST(GETDATE() AS DATE) 将当前日期和时间转换为仅日期值,例如返回 2010 年 4 月 6 日的 '2010-04-06'。添加一天基本上会选择今天的所有日期时间值。

在 SQL Server 2005 中,没有简单的方法可以做到这一点 - 最优雅的解决方案 I found here 是使用 DATETIME 的数字操作来实现相同的结果:

SELECT (list of fields)
FROM dbo.YourTable
WHERE dateValue BETWEEN 
   CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME) AND 
   DATEADD(DAY, 1, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))

【讨论】:

  • @marc_s - 你刚刚删除了你的答案吗?当我试图添加评论时,我吓坏了。如果我只是 cud 升级。非常感谢您的帮助。
  • @Chin: 是的,我先有一个愚蠢的答案,删除它,编辑它,然后再次取消删除它:-)
  • @marc_s:你肯定对“优雅”这个词有一个疯狂的定义,+1 :)
  • 好的 - 我认为 PostMan 仅提取 DATETIME 的日期部分的方法可能更加优雅 ;-)
  • @Chin:如果你在 datetime 字段上有索引,就性能而言应该还可以。如果将 Year、Month、Day 三个部分作为计算字段添加到表中,并在这三个字段上放置索引,那就更好了,因为它只需要进行相等匹配(Year=2010,Month=04,Day =06) 而不是范围查询。
【解决方案2】:

在 SQL 2000 和 SQL 2005 中,您可以使用一个不错的 select 语句从 DateTime 中删除时间组件,即

SELECT DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0)

将于 2010 年 4 月 6 日返回(仅限今天)。

结合 marc_s 的回答,你会想要

SELECT (list of fields)
FROM dbo.YourTable
WHERE dateValue BETWEEN DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 0) 
AND DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 1)

编辑:更改为适合要求,请注意第二个 DateAdd 中的 1(这会将它从一开始的天数添加到 1(而不是 0),使其成为 2010 年 4 月 7 日 00:00:00) 如果您想在 4 月 6 日 23:59:59 结束第二次约会,请稍等片刻

DATEADD(ss,-1,'My DateTime')

Final Call 将变为

DATEADD(ss,-1,DATEADD(dd, DATEDIFF(dd,0,'MY Date and Time, But I Only Want Date'), 1))

好的,这一次提供了很多信息!希望这一切都有意义:)

【讨论】:

  • 我喜欢你的表达方式,让仅日期部分比我的解决方案更好 - 但这个选择不起作用,不是吗?如果你有'2010-04-06 15:15:15' - 如何将它与日期部分进行比较?我认为您需要一种 WHERE dateValue BETWEEN (today) AND (today+1 day) 类型的选择来获取今天所有这些值,并附有任何时间部分......
  • 如果您想完全销毁索引,您可以在 DateValue 上使用 DateAdd/DatePart,但这是个坏主意! (如果你有好的索引:))
  • 我已经从报告中删除了介于 23:59:59.000 和第二天 00:00:00.000 之间的时间。所以我永远不会使用“减去一秒的方法”。最好将时间保持在 00:00:000.000 并增加一天,只需使用 "
【解决方案3】:

性能不好,但解决方案:

SELECT * 
FROM tblDate
WHERE CONVERT(VARCHAR, date, 112) = CONVERT(VARCHAR, GETDATE(), 112);

如果是普通查询,则应添加仅包含年-月-日内容的计算列。

【讨论】:

  • 你是对的,它会很慢,因为不会使用索引
【解决方案4】:

类似的东西

CONVERT(date,tbldata.date)=CONVERT(date,getdate())

这假定日期列也包括时间。如果没有,那么您可以将其更改为

tbldata.date=CONVERT(date,getdate())

【讨论】:

  • Sql Server 2005 有date 类型? ;)
  • 事实证明不是。我当前的堆栈是 SQL Server 2008,自从我们升级以来已经有一段时间了,我认为 2005 具有此功能。
【解决方案5】:

我已使用 UDF 对可追溯到 SQL 2000 的日期时间列执行此操作。

CREATE FUNCTION [dbo].[GETDATENOTIME](@now datetime)
RETURNS smalldatetime
AS
BEGIN
    RETURN (CONVERT(smalldatetime, CONVERT(varchar, @now, 112)))
END

用法:

DECLARE @date smalldatetime
SET @date = '4/1/10'
SELECT * FROM mytable WHERE dbo.GETDATENOTIME(date) = @date

这不是世界上最有效的东西(YMMV 取决于您的桌子),但它可以完成工作。对于我知道我会根据没有时间的日期进行选择的表,我将专门为此设置一个列,默认设置为 dbo.GETDATENOTIME(GETDATE())。

【讨论】:

  • 如果你曾经在“日期”列上有一个索引,这肯定不能使用它,从而导致表扫描......
  • 因此我的免责声明在最后。 OP要求简洁的语法,所以这就是我给他的答案。
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 2015-12-23
  • 2012-07-08
  • 2011-07-06
  • 2016-07-10
  • 2015-05-06
  • 2019-10-30
  • 1970-01-01
相关资源
最近更新 更多