Mic*_*art 5 sql t-sql sql-server sql-server-2005
我有两个表,我正在寻找一个表中的行,其中时间列不接近另一个表的时间列中的任何值.(近定义为一分钟内).
这是一个代码示例:
create table temp1
(
id int identity primary key,
value datetime not null
)
GO
create index ix_temp1 on temp1(value, id);
GO
set nocount on
insert temp1 (value) values (DATEADD(second, rand() * 1000000, '20100101'))
GO 15000
Run Code Online (Sandbox Code Playgroud)
表temp2设置相同:
create table temp2
(
id int identity primary key,
value datetime not null
)
GO
create index ix_temp2 on temp2(value, id);
GO
set nocount on
insert temp2 (value) values (DATEADD(second, rand() * 1000000, '20100101'))
GO 15000
Run Code Online (Sandbox Code Playgroud)
这是我的第一次破解(这是非常低效的)
SELECT t1.id, t1.value
FROM temp1 t1
LEFT JOIN temp2 t2
ON t1.value between DATEADD(MINUTE, -1, t2.value) and DATEADD(MINUTE, 1, t2.value)
WHERE t2.value is null
Run Code Online (Sandbox Code Playgroud)
我正在寻找更有效地做到这一点的方法.将考虑所有解决方案(新索引,SSIS解决方案,CLR解决方案,临时表,游标等...)
当列不可为空时,LEFT JOIN/IS NULL 在 SQL Server 上的效率不如 NOT IN 或 NOT EXISTS -有关详细信息,请参阅此链接。
也就是说,这个:
SELECT t1.id,
t1.value
FROM temp1 t1
WHERE NOT EXISTS(SELECT NULL
FROM temp2 t2
WHERE t2.value BETWEEN DATEADD(MINUTE, -1, t1.value)
AND DATEADD(MINUTE, 1, t1.value))
Run Code Online (Sandbox Code Playgroud)
...仍然存在一个问题,即函数使用(IE:DATEADD)导致索引无用。当索引位于原始值上时,您正在更改列的数据(暂时,而不将其写回到表中)。
如果你想要精确度,我会失去选择。否则,如果您在将日期时间插入临时表之前更改日期时间,那么您将获得:
t1.value = t2.value