MS SQLdate只有没有时间
题
大家好,
我已经有一段时间困惑了很长一段时间,基本上使用T-SQL来实现DateTime SQLtypes。 本质上,我想要采取2008-12-1 14:30:12的date时间值,并使其2008-12-1 00:00:00。 我们为报告运行的查询中有很多在WHERE子句中使用了一个date值,但是我有一天的开始和结束date值,并使用BETWEEN,或者我find了其他方法。
目前我使用以下: WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam 
 不过,这似乎有点笨重。 我希望能有像CAST([tstamp] AS DATE)这样更简单的东西, 
有些地方在线推荐使用DATEPART()函数,但是最后我得到了这样的结果:
WHERE DATEPART(year, [tstamp]) = DATEPART(year, @dateParam) AND DATEPART(month, [tstamp]) = DATEPART(month, @dateParam) AND DATEPART(day, [tstamp]) = DATEPART(day, @dateParam)WHERE DATEPART(year, [tstamp]) = DATEPART(year, @dateParam) AND DATEPART(month, [tstamp]) = DATEPART(month, @dateParam) AND DATEPART(day, [tstamp]) = DATEPART(day, @dateParam)
也许我太在意小事了,如果是的话,请让我知道。 我只是想确保我写的东西尽可能高效。 我想消除任何薄弱环节。
有什么build议么?
 谢谢, 
  C 
解
谢谢大家的好评。 很多有用的信息。 我将要改变我们的function,以消除操作员左侧的function。 虽然我们的大多数date列不使用索引,但它可能仍然是一个更好的做法。
这是非常糟糕的性能,看看只有在一个数据库你可以得到1000%+改善通过改变几行代码
操作员左侧的function不好
这是你需要做的
 declare @d datetime select @d = '2008-12-1 14:30:12' where tstamp >= dateadd(dd, datediff(dd, 0, @d)+0, 0) and tstamp < dateadd(dd, datediff(dd, 0, @d)+1, 0) 
运行这个来看看它做了什么
 select dateadd(dd, datediff(dd, 0, getdate())+1, 0) select dateadd(dd, datediff(dd, 0, getdate())+0, 0) 
如果您正在使用SQL Server 2008,现在已经内置了这个function,请在网上参阅书籍
 CAST(GETDATE() AS date) 
其他人发布的date函数是处理这个问题的最正确的方法。
然而,你提到“floor”这个词是很有趣的,因为这里有一点点黑客会跑得更快:
 CAST(FLOOR(CAST(@dateParam AS float)) AS DateTime) 
  CONVERT(date, GETDATE())和CONVERT(time, GETDATE())在SQL Server 2008中工作。我不确定2005年。 
这个怎么样?
 SELECT DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0) 
是的,T-SQL有时候会觉得非常原始,而这些东西往往会促使我用自己select的语言(如C#)来做很多我的逻辑。
然而,当你出于性能的原因绝对需要在SQL中做这些事情时,最好的办法是创build函数来容纳这些“algorithm”。
看看这篇文章。 他提供了很多方便的SQL函数,我认为这些函数可以帮助你。
http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx
 仔细一点,如果使用WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam东西,它将强制对表进行扫描,并且没有索引将用于该部分。 
更简洁的方法是定义一个计算列
 create table #t ( d datetime, d2 as cast (datepart(year,d) as varchar(4)) + '-' + right('0' + cast (datepart(month,d) as varchar(2)),2) + '-' + right('0' + cast (datepart(day,d) as varchar(2)),2) ) -- notice a lot of care need to be taken to ensure the format is comparable. (zero padding) insert #t values (getdate()) create index idx on #t(d2) select d2, count(d2) from #t where d2 between '2008-01-01' and '2009-01-22' group by d2 -- index seek is used 
这样,您可以直接检查d2列,并使用索引,而不必在转换过程中搞清楚。
 DATEADD(d, 0, DATEDIFF(d, 0, [tstamp])) 
编辑:虽然这将删除您的date时间的一部分,它也将使条件不可SARGable 。 如果这对于这个查询来说很重要,那么索引视图或者一个between子句是比较合适的。
或者你可以使用
 declare @d datetimeselect @d = '2008-12-1 14:30:12' where tstamp BETWEEN dateadd(dd, datediff(dd, 0, @d)+0, 0) AND dateadd(dd, datediff(dd, 0, @d)+1, 0) 
这是一个查询,将返回在一定范围内的所有结果。
 DECLARE @startDate DATETIME DECLARE @endDate DATETIME SET @startDate = DATEADD(day, -30, GETDATE()) SET @endDate = GETDATE() SELECT * FROM table WHERE dateColumn >= DATEADD(day, DATEDIFF(day, 0, @startDate), 0) AND dateColumn < DATEADD(day, 1, DATEDIFF(day, 0, @endDate)) 
FWIW,多年来我一直在做同样的事情
 CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam 
在我看来,这是在灵活性,速度和可读性方面剥离时间的更好方法之一。 (抱歉)。 build议的一些UDF函数可能是有用的,但UDF可能会较慢,更大的结果集。
 WHERE DATEDIFF(day, tstamp, @dateParam) = 0 
如果你不在乎时间,这应该让你在那里。
这是为了回答在不关心时间的情况下比较两个值的date的元问题。