在SQL Server中删除部分日期时间的最佳方法



Answers

在SQL Server 2008中,您可以使用:

CONVERT(DATE, getdate(), 101)
Question

从SQL Server的日期时间字段中删除时间部分时,哪种方法提供最佳性能?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

要么

b) select cast(convert(char(11), getdate(), 113) as datetime)

第二种方法确实发送了几个字节,但这可能不如转换速度那么重要。

两者似乎都非常快,但是在处理数百个或更多行时速度可能会有所不同。

另外,有没有可能有更好的方法来摆脱SQL中的日期时间部分?




SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)



如何select cast(cast my_datetime_field as date) as datetime) ? 这导致相同的日期,时间设置为00:00,但避免任何转换为​​文本,并避免任何明确的数字舍入。




首先解决插入/更新时间问题。 对于即时转换,没有任何东西可以胜任明智的用户定义函数:

select date_only(dd)

date_only的实现可以是任何你喜欢的 - 现在它被抽象出来,并且调用代码要干净得多。




在这里我创建了一个函数来删除SQL Server的日期时间的某些部分。 用法:

  • 第一个参数是要剥离的日期时间。
  • 第二个参数是char:
    • 秒:几秒钟; 删除毫秒
    • 米:轮到分钟; 移除秒和毫秒
    • h:几个小时; 删除分钟,秒和毫秒。
    • d:几天到几天; 删除小时,分钟,秒和毫秒。
  • 返回新的日期时间

create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end




已经回答,但不适当的抛出这里...这suposely也preform很好,但它的工作原理是抛出浮点数的小数(它存储时间),并只返回整个部分(这是日期)

 CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)

第二次,我发现这个解决方案... 我抓住了这个代码




这是另一个答案,来自另一个重复的问题:

SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime) 

这个神奇数字方法比DATEADD方法执行速度稍快。 (看起来〜10%)

CPU时间几百万记录:

DATEADD   MAGIC FLOAT
500       453
453       360
375       375
406       360

但请注意,这些数字可能无关紧要,因为它们已经非常快。 除非我有100,000或更多的记录集,否则我甚至无法将CPU时间读取到零以上。

考虑到DateAdd是为了这个目的而且更健壮的事实,我会说使用DateAdd。




对我来说,下面的代码永远是赢家:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));



就我个人而言,如果处理SQL Server 2005(或更低版本),我个人几乎总是使用用户定义函数 ,但是,应该指出的是,使用UDF有特定的缺陷,尤其是将它们应用于WHERE子句时有关此答案的评论以获取更多详细信息)。 如果使用SQL Server 2008(或更高版本) - 请参阅下文。

实际上,对于我创建的大多数数据库,我在开始时添加了这些UDF,因为我知道有99%的机会迟早需要它们。

我为“仅限日期”和“仅限时间”创建了一个(尽管“仅限日期”是迄今为止最常用的两个)。

以下是与各种与日期相关的UDF的链接:

基本的SQL Server日期,时间和日期时间函数
取得日期功能

最后一个链接显示了不少于3种不同的方式来获取仅日期时间字段的一部分,并提到每种方法的优点和缺点。

如果使用UDF,应该注意,您应该尽量避免将UDF用作查询中的WHERE子句的一部分,因为这会极大地妨碍查询的性能。 造成这种情况的主要原因是在WHERE子句中使用UDF会将该子句呈现non-sargable ,这意味着SQL Server不能再使用具有该子句的索引来提高查询执行的速度。 关于我自己对UDF的使用,我会经常在WHERE子句中使用“raw”日期列,但是将UDF应用到SELECTed列。 这样,UDF仅应用于过滤结果集,而不是表格的每一行作为过滤器的一部分。

当然,绝对最好的方法是使用SQL Server 2008(或更高版本)并分离出日期和时间 ,因为SQL Server数据库引擎然后本地提供单独的日期和时间组件,并且可以高效地独立查询这些而不需要UDF或其他机制从复合日期时间类型中提取日期或时间部分。




选择CONVERT(char(10),GetDate(),126)




我很喜欢:

[date] = CONVERT(VARCHAR(10), GETDATE(), 120)

120格式代码将把日期强制转换为ISO 8601标准:

'YYYY-MM-DD' or '2017-01-09'

在dplyr( R )和pandas( Python )中使用超级简单!






Links