Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 以十分之一秒的精度获得日期差异的最佳方法_Sql_Sql Server_Tsql_Date_Datediff - Fatal编程技术网

Sql 以十分之一秒的精度获得日期差异的最佳方法

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) ) 除了这个比较大之外,

我有一个表,有两个日期和一个浮点值,这是两个日期的差,以秒为单位,小数点为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标准的地方,以及在多大程度上。。。马可