Sql 以十分之一秒的精度获得日期差异的最佳方法
我有一个表,有两个日期和一个浮点值,这是两个日期的差,以秒为单位,小数点为1 这就是我正在使用的:Sql 以十分之一秒的精度获得日期差异的最佳方法,sql,sql-server,tsql,date,datediff,Sql,Sql Server,Tsql,Date,Datediff,我有一个表,有两个日期和一个浮点值,这是两个日期的差,以秒为单位,小数点为1 这就是我正在使用的: CREATE TABLE [dbo].[table]( --timestamp and id [start] datetime NULL, [end] datetime NULL, [dif] AS ROUND(datediff(millisecond,[start],[end])/1000.0,1) ) 除了这个比较大之外,
CREATE TABLE [dbo].[table](
--timestamp and id
[start] datetime NULL,
[end] datetime NULL,
[dif] AS ROUND(datediff(millisecond,[start],[end])/1000.0,1)
)
除了这个比较大之外,它似乎不是很有效。做同样的事情有更好的方法吗?例如:DateDiffSecondTexth、[start]、[end]/10.0这不是特定于SQL Server的,而是ANSI SQL,并且受到许多DBMS-s的支持 First-DATETIMEs通常不是获取秒数的数据类型。我将使用时间戳,默认刻度为6微秒,与ANSI标准相同 话虽如此,除了DATEDIFF之外,我们还有TIMESTAMPDIFF。但日期部分可能是秒、毫秒或微秒。真倒霉 解决方法是将TIMESTAMPDIFF返回的整数除以100,并将结果硬转换回整数。现在,一些DBMS在执行此操作时会截断为FLOORnumber::INTEGER,即带有小数点的数字。如果MS SQL做到了这一点,只需将0.5除以100,然后再进行硬转换。无论如何,这比一轮要快得多 我使用_start和_end作为列名,以避免保留字并保持在ANSI标准内。自由,自由,便携 请看这里:
WITH foo(the_start,the_end) AS (
SELECT TIMESTAMP '2017-01-11 07:31:26.016270',TIMESTAMP '2017-01-11 07:31:43.190093'
UNION ALL SELECT TIMESTAMP '2017-01-11 07:31:51.952073',TIMESTAMP '2017-01-11 07:31:52.091006'
UNION ALL SELECT TIMESTAMP '2017-01-11 07:32:10.305528',TIMESTAMP '2017-01-11 07:32:35.460201'
UNION ALL SELECT TIMESTAMP '2017-01-11 07:32:35.460201',TIMESTAMP '2017-01-11 07:32:35.599238'
)
SELECT
the_start
, the_end
, TIMESTAMPDIFF(millisecond, the_start,the_end) AS diff_ms
, CAST(TIMESTAMPDIFF(millisecond, the_start,the_end)/100 AS INT) AS diff_tenth_sec
FROM foo;
the_start |the_end |diff_ms|diff_tenth_sec
2017-01-11 07:31:26.016270|2017-01-11 07:31:43.190093| 17,174| 172
2017-01-11 07:31:51.952073|2017-01-11 07:31:52.091006| 139| 1
2017-01-11 07:32:10.305528|2017-01-11 07:32:35.460201| 25,155| 252
2017-01-11 07:32:35.460201|2017-01-11 07:32:35.599238| 139| 1
玩得开心-
Marco the Sane这里是一个绕过一些潜在溢出问题的示例,任何超过23天的间隔都会使datediff出现溢出,但这将持续数十年
declare @start as datetime;
declare @end as datetime;
set @start = '20100701 10:10:10.125';
set @end = '20100702 10:10:10.225';
select round((cast(@end as float) - cast(@start as float)) * 24 * 3600, 1);
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
通过这项测试,我发现性能几乎没有差异,这是一千万次计算,在我的电脑上,这两组都需要13秒
declare @start as datetime;
declare @end as datetime;
DECLARE @MS as float;
DECLARE @I as int;
SET @I = 0;
SET @START = getdate();
WHILE @I < 10000000
BEGIN
SET @MS = round((cast(getdate() as float) - cast(@start as float)) * 24 * 3600, 1);
SET @I = @I + 1;
END
PRINT @MS;
SET @START = getdate();
SET @I= 0;
WHILE @I < 10000000
BEGIN
SET @MS = ROUND(datediff(millisecond,@start,getdate())/1000.0,1)
SET @I = @I + 1;
END
PRINT @MS;
你的表情很好。唯一真正的问题是溢出问题,如果返回值太大而无法存储在整数中。为什么要存储diff列呢??您不能在运行时计算吗?我认为您使用计算字段的方法是可以的,顺便说一句,避免溢出可能很棘手-您正在处理的日期范围是什么?它可以工作的范围不是那么大,你似乎无法在几周内获得毫秒时差-它不仅仅是存储值,datediff能否提供毫秒也是一个问题difference@GordonLinoff这两个日期的间隔不太可能超过1小时。因此,当使用CONVERTfloat时,你得到了20世纪第一天的天数?这比我的方法快吗?@nickzoum也许你最好检查一下它是否快?!带有浮点数和日期的数值计算应该很快。如果您看到更改带来的性能提升,我会感到惊讶-您是否认为当前的计算结果会影响性能?我希望展示的好处是消除数字溢出风险。对100万个条目进行了两种方法的测试,该方法又花了1秒25 vs 26完成了5次测试,结果完全相同。示例中使用的时间戳和时间戳差异在SQL Server中不可用。时间戳作为一种数据类型存在,但它是一种与日期/时间无关的数据类型-谢谢,克里斯-总是乐于学习新事物。。。。特别是在支持ANSI标准的地方,以及在多大程度上。。。马可