Jul*_*sar 265 sql-server datetime truncate sql-server-2008
在SQL Server 2008中截断日期时间值(删除小时分钟和秒)的最佳方法是什么?
例如:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
Joe*_*orn 471
这继续经常收集额外的投票,甚至几年后,所以我需要为现代版本的Sql Server更新它.对于Sql Server 2008及更高版本,它很简单:
cast(getDate() As Date)
Run Code Online (Sandbox Code Playgroud)
请注意,底部附近的最后三段仍然适用,您通常需要退后一步,找到一种方法来避免演员阵容.
但也有其他方法可以实现这一目标.这是最常见的.
正确的方法(自Sql Server 2008以来的新方法):
cast(getdate() As Date)
Run Code Online (Sandbox Code Playgroud)
正确的方法(旧):
dateadd(dd, datediff(dd,0, getDate()), 0)
Run Code Online (Sandbox Code Playgroud)
这个现在已经老了,但它仍然值得知道,因为它也可以很容易地适应其他时间点,比如月,分,小时或年的第一个时刻.
这种正确的方法使用了作为ansi标准一部分的文档化函数,并保证可以正常工作,但它可能会慢一些.它的工作原理是查找从第0天到当天的天数,并将这几天添加到第0天.无论您的日期时间是如何存储的,无论您的语言环境如何,它都能正常工作.
快捷方式:
cast(floor(cast(getdate() as float)) as datetime)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为datetime列存储为8字节二进制值.将它们转换为浮动,将它们放置以移除分数,并且当您将它们转换回日期时间时,值的时间部分将消失.它只是位移,没有复杂的逻辑,而且速度非常快.
请注意,这依赖于实现细节Microsoft可以随时更改,即使在自动服务更新中也是如此.它也不是很便携.在实践中,这种实施很可能不会很快改变,但是如果你选择使用它,那么了解危险仍然很重要.现在我们可以选择投射日期,这很少是必要的.
错误的方法:
cast(convert(char(11), getdate(), 113) as datetime)
Run Code Online (Sandbox Code Playgroud)
错误的方法是转换为字符串,截断字符串,然后转换回日期时间.这是错误的,原因有二:1)它可能无法在所有语言环境中运行; 2)它是关于最慢的可行方式......而不仅仅是一点点; 它比其他选项慢一个数量级或两个数量级.
更新这最近得到了一些投票,所以我想补充说,自从我发布这个以来,我已经看到一些非常可靠的证据表明Sql Server将优化"正确"方式和"快速"方式之间的性能差异,这意味着你现在应该支持前者.
在任何一种情况下,您都希望编写查询以避免首先执行此操作.你应该在数据库上做这项工作是非常罕见的.
在大多数地方,数据库已经成为你的瓶颈.通常,服务器是增加硬件以提高性能的最昂贵的服务器,也是最难获得正确添加硬件的服务器(例如,您必须平衡磁盘与内存).从技术角度和商业角度来看,它也是最难扩展的; 在技术上添加Web或应用程序服务器比数据库服务器更容易,即使这是假的,您也不需要为IIS或Apache支付每服务器许可证20,000美元.
我想说的是,只要有可能,你应该在应用程序级别完成这项工作.你应该发现自己在Sql Server上截断日期时间的唯一一次是当你需要按日分组时,即使这样你也应该有一个额外的列设置为计算列,保持在插入/更新时间,或维护在应用程序逻辑.从数据库中获取这个破坏索引,重大cpu的工作.
DJ.*_*DJ. 44
仅适用于SQL Server 2008
CAST(@SomeDateTime AS Date)
Run Code Online (Sandbox Code Playgroud)
然后如果你愿意,把它重新投入日期时间
CAST(CAST(@SomeDateTime AS Date) As datetime)
Run Code Online (Sandbox Code Playgroud)
Luc*_*ero 21
只是为了更完整的答案,这里是一个截断到任何日期部分的工作方式,包括分钟(用GETDATE()截断日期替换).
这与接受的答案不同,您不仅可以使用dd(天),还可以使用任何日期部分(请参阅此处):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
Run Code Online (Sandbox Code Playgroud)
请注意,在上面的表达式中,它0是一年开始时的常量日期(1900-01-01).如果需要截断为较小的部分,例如秒或毫秒,则需要采用更接近截断日期的常量日期以避免溢出.
我必须这样做时在网上找到的片段是:
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
500841 次 |
| 最近记录: |