Answers:
即使在几年之后,这种情况仍会继续频繁地获得更多投票,因此我需要针对Sql Server的现代版本进行更新。对于Sql Server 2008和更高版本,它很简单:
cast(getDate() As Date)
请注意,底部附近的最后三段仍然适用,并且您通常需要退后一步,找到一种方法来避免转换。
但是,还有其他方法可以实现此目的。这是最常见的。
正确的方法(自Sql Server 2008以来新增):
cast(getdate() As Date)
正确的方法(旧):
dateadd(dd, datediff(dd,0, getDate()), 0)
现在已经比较老了,但是仍然值得知道,因为它还可以轻松适应其他时间点,例如月份,分钟,小时或年份的第一时刻。
这种正确的方式使用了已记录的功能,这些功能是ansi标准的一部分,可以保证正常工作,但速度可能会稍慢。它的工作原理是找到从第0天到当前天有多少天,然后将这些天加回到第0天。无论您存储日期时间的方式如何,无论您的语言环境是什么,它都可以工作。
快速方法:
cast(floor(cast(getdate() as float)) as datetime)
之所以可行,是因为datetime列存储为8字节二进制值。将其强制转换为浮点数,将其压下以删除小数部分,然后将其强制转换为日期时间时,值的时间部分将消失。一切都只是在没有复杂逻辑的情况下发生了变化,而且速度非常快。
请注意,这取决于实施细节Microsoft即使在自动服务更新中也可以随时更改。它也不是很便携。在实践中,这种实现不太可能很快改变,但是,如果选择使用它,务必要意识到其危险,这一点仍然很重要。现在,我们可以选择将日期转换为日期,因此几乎没有必要。
错误的方法:
cast(convert(char(11), getdate(), 113) as datetime)
错误的方式是转换为字符串,截断字符串并转换回日期时间。这是错误的,原因有两个:1)可能无法在所有地区使用,而且2)这是最慢的操作方式……而不仅仅是一点点;这比其他选项要慢一个数量级或两个数量级。
更新最近,这已经获得了一些票,因此,我想补充一点,自从我发布此文章以来,我已经看到了一些非常有力的证据,证明Sql Server将消除“正确”方式和“快速”方式之间的性能差异。 ,这意味着您现在应该支持前者。
在任何一种情况下,您都希望编写查询,以避免首先需要这样做。您很少在数据库上执行此工作。
在大多数地方,数据库已经成为您的瓶颈。通常,在服务器上添加硬件以提高性能最昂贵,而最难于正确添加这些内容的服务器(例如,必须使磁盘与内存保持平衡)。从技术上和从业务的角度来看,它也是最难向外扩展的。从技术上讲,添加Web或应用程序服务器要比数据库服务器容易得多,即使这是错误的,您也不必为IIS或Apache支付每服务器许可证20,000美元以上的费用。
我要说明的一点是,只要有可能,就应该在应用程序级别执行此工作。在只有你应该发现自己截断SQL Server的日期时间时间是当你需要组按天,甚至那么你或许应该有一个额外的列设置为计算列,保持在插入/更新时间,或维持在应用程序逻辑中。使您的数据库摆脱索引中断,繁重的工作。
cast(getdate() as date)
呢?
getdate()
这是您可能拥有的任何日期时间源的替代品。
只是为了获得更完整的答案,这是一种截断日期部分(包括分钟)的工作方法(用截断日期代替GETDATE()
)。
这与接受的答案不同,因为您不仅可以使用dd
(天),而且可以使用任何日期部分(请参见此处):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
请注意,在上面的表达式中,0
是一年初(1900-01-01)的恒定日期。如果需要截断较小的部分(例如秒或毫秒),则需要采用一个恒定的日期,该日期应更接近于被截断的日期,以避免溢出。
dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
我必须在网上找到的代码段是:
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
DateAdd(dd, DateDiff(...), 0)
。如果您不小心,可能会咬伤您。
在SQl 2005中,可以这样编写trunc_date函数。
(1)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
第一种方法要干净得多。它仅使用3个方法调用,包括最后的CAST(),并且不执行字符串连接,这是自动加号。此外,这里没有巨大的类型转换。如果您可以想象可以表示日期/时间戳,那么从日期转换为数字然后再转换回日期是一个相当简单的过程。
(2)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CONVERT(varchar, @date,112)
END
如果您担心Microsoft对日期时间(2)或(3)的实现,则可以。
(3)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END
第三,更冗长的方法。这需要将日期分为年,月和日部分,以“ yyyy / mm / dd”格式将它们放在一起,然后将其转换回日期。此方法涉及7个方法调用,包括最终的CAST(),更不用说字符串连接了。
选择cast(floor(cast(get(getdate()as float))作为日期时间))引用此:http : //microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html
对于那些来这里寻求将DATETIME字段截断为不到一整天(例如每分钟)的方法的人,可以使用以下方法:
SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)
所以如果今天是这样的话,2010-11-26 14:54:43.123
那将会回来的2010-11-26 14:54:00.000
。
要更改其实际间隔,请用一天中的间隔数替换1440.0,例如:
24hrs = 24.0 (for every hour)
24hrs / 0.5hrs = 48.0 (for every half hour)
24hrs / (1/60) = 1440.0 (for every minute)
(始终将a .0
放在末尾以隐式转换为浮点数。)
对于那些你想知道的东西(3.0/86400000)
是在我的计算,SQL Server 2005不似乎从铸造FLOAT
到DATETIME
准确,所以这增加了3毫秒地板之前。
datetime2
数据类型。
此查询应为您提供trunc(sysdate)
与Oracle中相同的结果。
SELECT *
FROM your_table
WHERE CONVERT(varchar(12), your_column_name, 101)
= CONVERT(varchar(12), GETDATE(), 101)
希望这可以帮助!
您还可以using Substring
从datetime变量中提取日期,并强制转换回datetime将忽略时间部分。
declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
另外,您可以访问datetime变量的各个部分,并将它们合并到一个截断日期的构造中,如下所示:
SELECT cast(DATENAME(year, @Somedate) + '-' +
Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
DATENAME(day, @Somedate)
as datetime)
TRUNC(aDate,'DD')将截断分钟,秒和小时
SRC:http://www.techonthenet.com/oracle/functions/trunc_date.php