【问题标题】:Extract time from datetime efficiently (as decimal or datetime)有效地从日期时间中提取时间(作为十进制或日期时间)
【发布时间】:2012-08-14 07:58:00
【问题描述】:

我已经能够找到很多信息,用于从日期时间列(如this one)获取时间的字符串表示形式。

我需要从日期时间中取出时间部分,以便我可以对其进行一些数学运算,例如将其添加到另一个日期时间中。所以时间的字符串表示对我没有帮助。

但是我只找到了一个example,它将时间提取为数字类型值。即:

SELECT CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))

这个方法需要 两个 强制转换,我必须在超过 10,000 行上运行它。有没有类似于dateadd 方法从日期时间列中提取日期部分的方法,即:

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

我可以用来从日期时间列中获取时间并将其作为小数或日期时间返回?也许是一个使用较少铸造的解决方案?

我使用的是 SQL Server 2000。

【问题讨论】:

  • 转换的目的是什么?
  • 我必须将事件的时间值添加到仅日期值,以便我可以将其与另一个表进行比较作为连接的一部分。我必须从另一个包含事件类型的日期和时间的表中提取事件类型的时间值。
  • 当你说“数值”时,请注意这必须是毫秒、分钟或其他时间值的计数,不是浮点数或小数,因为那些不不行!试试SELECT Convert(datetime, Convert(decimal(38, 31), Convert(datetime, '2012-08-17 00:00:00.003')))。这产生2012-08-17 00:00:00.000。哎呀。 float 也有同样的问题。

标签: sql datetime sql-server-2000


【解决方案1】:

以秒为单位获取时间的一种方法是:

select cast(datediff(second, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0), getdate())/(60*60*24.0) as datetime)

这会以秒为单位计算时间,然后转换回日期时间。

以小数形式获取:

select datediff(second, DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0), getdate())/(60*60*24.0)

如果您更喜欢毫秒精度,请使用“ms”。

或者,您可以使用更具可读性:

select datepart(hh, getdate())/24.0+datepart(mm, getdate())/(24*60.0)+
       datepart(ss, getdate())/(24*60*60.0)

【讨论】:

  • 这看起来可行,知道它处理所有额外数学的速度是否比两次投射快吗?我对 SQL 处理速度不是很了解。
  • 只有 10,000 条记录,我不会担心。如果您正在处理每行 50 次强制转换和数百万行,那么您可能会开始提高性能。演员阵容可能更快。
【解决方案2】:

获取datetime

SELECT GetDate() - DateDiff(day, 0, GetDate());
-- returns the time with zero as the datetime part (1900-01-01).

并得到一个代表时间的数字:

SELECT DateDiff(millisecond, DateDiff(day, 0, GetDate()), GetDate());
-- time since midnight in milliseconds, use as you wish

如果你真的想要一个字符串,那么:

SELECT Convert(varchar(8), GetDate(), 108); -- 'hh:mm:ss'
SELECT Convert(varchar(12), GetDate(), 114); -- 'hh:mm:ss.nnn' where nnn is milliseconds

【讨论】:

  • 第一个似乎是最简单的。
  • 需要十进制或日期时间,因为我必须在 SQL 中对结果进行更多处理。第一个就可以了。
  • 不要使用decimal!!!它不会工作!试试SELECT Convert(datetime, Convert(decimal(38, 31), Convert(datetime, '2012-08-17 00:00:00.003')))。这产生2012-08-17 00:00:00.000。哎呀。 float 也有同样的问题。
  • 第一个仍然有效,因为它是一个日期时间,对吧?我假设我可以安全地将结果添加到另一个日期时间?
猜你喜欢
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多