我如何截断SQL Server中的date时间?
在SQL Server 2008中截断date时间值的最佳方法是什么(以消除小时和分钟)?
例如:
declare @SomeDate datetime = '2009-05-28 16:30:22' select trunc_date(@SomeDate) ----------------------- 2009-05-28 00:00:00.000
这仍然经常会收集更多的选票,甚至几年后,所以我需要更新它的现代版本的Sql Server。 对于Sql Server 2008及更高版本,这很简单:
cast(getDate() As Date)
请注意,靠近底部的最后三段仍然适用,你经常需要退后一步,find一种方法来避免演员摆在首位。
但是还有其他方法可以做到这一点。 这是最常见的。
正确的方法(自Sql Server 2008以来新增):
cast(getdate() As Date)
正确的方法(旧):
dateadd(dd, datediff(dd,0, getDate()), 0)
现在这个年龄比较大,但是还是值得一提的,因为它也可以很容易地适应其他时间点,比如月,分,小时或者年的第一时刻。
这种正确的方法使用文档化的function,是ANSI标准的一部分,并保证工作,但可能会稍微慢一些。 它通过查找从第0天到当天有多less天,并将这些天添加到第0天。无论您的date时间如何存储以及不pipe您的语言环境如何,它都将起作用。
快速的方法:
cast(floor(cast(getdate() as float)) as datetime)
这是有效的,因为date时间列存储为8字节的二进制值。 将它们转换为浮动状态,将它们放置以除去小数部分,并且在将它们转换回date时间时,值的时间部分将消失。 这只是一点点转变,没有复杂的逻辑,而且速度非常快。
请注意,这依赖于实现细节,微软可以随时更改,即使在自动更新服务中也是如此。 这也不是很便携。 在实践中,这个实现不太可能很快就会改变,但是如果你select使用它,那么意识到这个危险是很重要的。 而现在我们可以select投射date,这是很less有必要的。
错误的方法:
cast(convert(char(11), getdate(), 113) as datetime)
错误的方式通过转换为string,截断string,并转换回date时间。 这是错误的 ,原因有两个:1)它可能不适用于所有地区,2)它是关于尽可能慢的方法来做到这一点…而不仅仅是一点; 这比其他选项慢了一两个数量级。
更新这最近得到了一些选票,所以我想补充说,自从我发布这个,我已经看到了一些非常可靠的证据,Sql Server将优化“正确”的方式和“快速”方式之间的性能差异这意味着你现在应该倾向于前者。
在这两种情况下,您都希望编写查询以避免首先执行此操作 。 你应该在数据库上做这个工作是非常罕见的。
在大多数地方,数据库已经是你的瓶颈。 一般来说,增加硬件来提高性能是最为昂贵的服务器,也是最难添加硬件的服务器(例如,您必须平衡磁盘和内存之间的关系)。 在技术上和从商业angular度来看,这也是最难扩展的。 在技术上,添加Web或应用程序服务器要比数据库服务器简单得多,即使这样做不对,您也不用为IIS或Apache支付每服务器许可证$ 20,000 +。
我试图说的是,只要有可能,你应该在应用程序级别上做这个工作。 唯一一次你应该发现自己截断Sql Server上的date时间是当你需要按日进行分组的时候,即使这样你也许应该有一个额外的列设置为一个计算列,保持在插入/更新时间,或维护在应用程序逻辑。 从数据库中获取这个索引突破,CPU繁重的工作。
仅适用于SQL Server 2008
CAST(@SomeDateTime AS Date)
然后如果你愿意的话,把它转换回date时间
CAST(CAST(@SomeDateTime AS Date) As datetime)
只是为了更完整的回答,这里有一个工作方式,截断任何date部分,包括分钟(用截断datereplaceGETDATE()
)。
这不同于接受的答案,因为您不仅可以使用dd
(天),而且可以使用任何date部分(请参阅此处 ):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
请注意,在上面的expression式中, 0
是一年(1900-01-01)开始的常量date。 如果您需要截断较小的部分,例如几秒或几毫秒,则需要采用一个接近截断date的常量date以避免溢出。
我必须这样做时,我在网上find的片段是:
dateadd(dd,0, datediff(dd,0, YOURDATE)) eg dateadd(dd,0, datediff(dd,0, getDate()))
在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()并且不执行string连接,这是一个自动加号。 此外,这里没有大型的演员。 如果您可以想象date/时间戳可以表示,那么从date转换为数字并返回date是一个相当简单的过程。
(2)
CREATE FUNCTION trunc_date(@date DATETIME) RETURNS DATETIME AS BEGIN SELECT CONVERT(varchar, @date,112) END
如果你担心微软的date时间(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
第三,比较详细的方法。 这需要将date分成年,月和日,将它们放在“yyyy / mm / dd”格式中,然后再将其转换回date。 这个方法涉及7个方法调用,包括最终的CAST(),更不用说string连接了。
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
你可以这样做(SQL 2008):
declare @SomeDate date = getdate()
select @SomeDate
2009-05-28
selectcast(floor(cast(getdate()as float))作为date时间)参考: 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.0replace为一天中的时间间隔数,例如:
24hrs = 24.0 (for every hour) 24hrs / 0.5hrs = 48.0 (for every half hour) 24hrs / (1/60) = 1440.0 (for every minute)
(总是把一个.0
结尾隐式地转换成一个浮点数。)
对于那些想知道(3.0/86400000)
在我的计算中是什么的人来说,SQL Server 2005似乎不能准确地从FLOAT
到DATETIME
,所以在铺设它之前增加了3毫秒。
这个查询应该给你相当于Oracle中trunc(sysdate)
结果。
SELECT * FROM your_table WHERE CONVERT(varchar(12), your_column_name, 101) = CONVERT(varchar(12), GETDATE(), 101)
希望这可以帮助!
你也可以using Substring
从date时间variables的using Substring
提取date,并且回到date时间将忽略时间部分。
declare @SomeDate datetime = '2009-05-28 16:30:22' SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
另外,你可以访问datetimevariables的一部分,并将它们合并到构造截断date,如下所示:
SELECT cast(DATENAME(year, @Somedate) + '-' + Convert(varchar(2),DATEPART(month, @Somedate)) + '-' + DATENAME(day, @Somedate) as datetime)
甲骨文:
TRUNC(SYSDATE, 'MONTH')
SQL Server:
DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)
可以同样用于从date截断分钟或小时。
TRUNC(aDate,'DD')将截断min,sec和hrs
SRC: http : //www.techonthenet.com/oracle/functions/trunc_date.php
- 生成一个时间间隔之间的date时间列表
- DateTime.Compare如何检查date是否小于30天?
- 如果我的传入date格式是YYYYMMDD,则在.NET中将string转换为date
- 我如何设置一个NSDate对象到午夜?
- DateTime.Now.Ticks如何正确工作?
- 如何获取Ruby on Rails中两个DateTime之间的秒数
- 如何将Joda-Time DateTime转换为java.util.Date,反之亦然?
- 为什么DateTime.ParseExact(String,String,IFormatProvider)需要IFormatProvider?
- 将dd / mm / yyyy格式的string转换为Datetime