通过datetimefield SQL Server加入

时间:2009-06-15 16:59:02

标签: sql sql-server join

我有两张表可以保存SKU的信息。

日志表有datetimefield 2008-10-26 06:21:59.820
另一张表有datetimefield 2008-10-26 06:22:02.313

我希望将这个日期时间字段包含在这两个表的连接中。

是否可以加入具有差异不超过3秒的日期时间字段的表?最好的方法是什么?

7 个答案:

答案 0 :(得分:7)

这是一种方法:

select * from table_a, table_b
where table_a.sku = table_b.sku
and abs(datediff(second,table_a.datetime,table_b.datetime))<=3

小心,对于大桌子,这种连接可能会很慢。

答案 1 :(得分:5)

SELECT
  t1.id,
  t2.id
FROM
  t1
  INNER JOIN t2 ON ABS(DATEDIFF(ms, t1.datefield, t2.datefield)) <= 3000
WHERE
  ...

请注意,这会很慢。并且可能并不总是正确的(因为:它不会总是连接应该加入的记录,因为它们属于一起,它当然总是技术上正确)。

编辑:

由于@ richardtallent在评论中的出色表现,从ABS(DATEDIFF(ss, t1.datefield, t2.datefield)) <= 3更改为上述内容。

答案 2 :(得分:2)

有两种方式可以考虑:

... on other.date between dateadd(second,-3,log.date) and dateadd(second,3,log.date)

... on abs(datediff(millisecond, other.date, log.date)) <= 3000

检查哪一个可以提供最佳性能。

(编辑:在第二种选择中将秒数更改为毫秒,正如richardtallent在对不同答案的评论中指出的那样。)

答案 3 :(得分:2)

高效地执行它是一项挑战,因为您最终会直接使用表达式而不是字段值进行查询,而且此类查询不能很好地使用索引。

特别是,请勿使用DATEDIFF。

您可能有机会

WHATE DATEADD(ms,date1,3)&lt; date2 AND DATEADD(ms,date1,-3)&gt; DATE2

WHATE date2 BETWEEN DATEADD(ms,date1,3)和DATEADD(ms,date1,-3)

注意:如果插入从同一事件或事务派生出来,通常可以重构插入以具有完全相同的时间戳值(但是它们会有一些其他公共密钥,您不需要这样做。)< / p>

你也可以以较低的分辨率存储原始值 - 比如说全秒,甚至是分钟 - 这取决于你的要求,但是你仍然会遇到边界问题。

答案 4 :(得分:1)

您能否依赖于应匹配的行的日期时间值的顺序?例如,日志条目是否总是在进入另一个表之前?如果是这样,请修改上面的一个答案以删除ABS()函数(特别注意DATEDIFF参数的顺序)。这有助于防止错误匹配。

答案 5 :(得分:0)

SELECT tbl1.*, tbl2.*
FROM tbl1, tbl2
WHERE ABS(DATEDIFF(second, tb1.date, tbl2.date)) <= 3

答案 6 :(得分:0)

未经测试,但这应该有效......

Select *
From tbl1
  inner join tbl2 on tbl1.id=tbl2.id and 
     Datediff(second, tbl1.dttime, tbl2.dttime) between -3 and 3