2012-03-16 54 views
0

我左表中的每一行在右表中只有一個匹配(右表是包含所有行的主表;左表僅包含這些行的子集)。每個表中的行的時間戳不完全匹配,但通常在彼此的1秒內。因此,當我加入表格時,我必須使用:如何防止INNER JOIN返回多個匹配?

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

你可以嘗試不同的,或TOP 1. – 2012-03-16 21:15:35

+2

在您的where子句中的好方法,你的意思是 打開之間right_table.timestamp left_table.timestamp - 。 00015 AND right_table.timestamp + .00015 – David 2012-03-16 21:21:04

+0

我想這就是我要做的。我只是重新評估了這個問題,我認爲只要我使用「DISTINCT」就可以返回多個結果。時間跨度非常狹窄,以至於我需要從連接中獲取標準。謝謝! – eek142 2012-03-16 21:22:21

回答

1

如果您只需要精確到秒,就可以截斷您選擇的其餘部分。

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()函數內殺死任何在這些列上使用索引的機會。如果我有更多時間可以花費,我可能會把一些東西放在一起,這會對索引更友好......但也許不是,因爲這對我來說看起來像是弱桌面設計,真正的解決方法是添加一列更直接地鏈接記錄。

+0

我很欣賞這種努力。我會再看看這個,但我認爲DISTINCT現在可以滿足我的需求。 – eek142 2012-03-16 21:34:48

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 ........