左边表格中的每一行在右边的表格中只有一个匹配(右表是主表格,其中包含所有行;左表格只包含这些行的子集)。每个表中行的时间戳不完全匹配,但它们通常彼此相差1秒。因此,当我加入表格时,我必须使用:
FROM left_table INNER JOIN right_table
ON left_table.timestamp BETWEEN right_table.timestamp - .00015 AND right_table.timestamp + .00015
--This is approximately a 2 second wide range since this is a DATETIME field
AND left_table.name = right_table.name
AND ........
除时间戳外,其他所有条件都完全匹配。有办法解决这个问题吗?
大多数情况下,这足以仅返回1行,但有时当彼此之间存在两个相同的行时,它们都将被返回。
答案 0 :(得分:2)
这应该更准确。现在获得欺骗的唯一方法是,他们都有相同的时差:
FROM left_table
INNER JOIN
(
SELECT l.name, min(abs(r.timestamp - l.timestamp)) as offset
FROM left_table l
INNER JOIN right_table ON r on r.name=l.name
GROUP BY l.name
) lrmap ON left_table.name = lrmap.name
INNER JOIN right_table
ON left_table.name = right_table.name
AND abs(left_table.timestamp-right_table.timestamp) = lrmap.offset
但是,我不会保证性能,因为减法很慢并且将它们放在abs()函数中会杀死在这些列上使用索引的任何机会。如果我有更多的时间花在一起,我可能会把一些更友好的索引放在一起...但也许不是,因为这看起来像弱表设计给我,真正的修复将是添加一个列更直接地链接记录。
答案 1 :(得分:1)
如果您只需要精确到秒,那么您可以在选择中截断其余部分。
答案 2 :(得分:0)
where exists()
条款是防止笛卡尔积的好方法
FROM left_table lt
where exists(
select 1 from right_table
where lt.[timestamp] BETWEEN [timestamp] - .00015 AND [timestamp] + .00015
and lt.name=name
AND ........
)
AND ........