2010-07-06 52 views
2

我存儲一些間隔在SQL時間間隔,例如:檢查使用SQL條件

id INT 
from DATE 
to DATE 

如何檢查,僅使用一個狀態(如果可能),如果有一個新的區間衝突一個現有的?

例子:

|-----------| (from 1 to 5) 
    |-----------| (from 2 to 6) 
     |--| (from 3 to 4) 
        |--| (from 7 to 8) 

每間隔(前三)具有與其他兩個區間......除了最後一個是單獨有些抵觸。

-

可以使用一些條件等來實現此檢查:

WHERE (`from` <= $FROM and `to` >= $TO) 

但這只是檢查間隔是包含新一...不是其他的時間間隔,有一些十字路口或者裏面的那個這個新的。

也許這樣?

WHERE NOT (`from` < $FROM and `to` < $TO) AND NOT (`from` > $FROM and `to` > $TO) 

Obs .:我需要找到衝突來提醒用戶這個新時期已經存在或與現存的衝突存在衝突。

+0

你使用什麼樣的週期表示法,例如:關閉開?換句話說,你會考慮'(從1到5)'與'(從5到6)'碰撞嗎? – onedaywhen 2010-07-07 10:45:26

回答

2
WHERE ($TO >= `from` AND $FROM <= `to`) 

注意這適用於在新的範圍重疊的整個範圍,當它只是部分重疊,當它涵蓋了它以及時。

+0

+1,經典求職面試問題:) – Konerak 2010-07-06 18:23:34

+0

跆拳道!你是個天才! – 2010-07-06 18:26:56

+0

我以前在80年代在GIS系統中工作。交叉點和重疊是我的第二天性。 – 2010-07-06 18:27:49

3

我遇到了這個問題,只是想試圖展示真值表如何識別保羅已經發布的簡化邏輯。

假設您有一個間隔from [ to ],您要檢查from { to }

這意味着下面的真值表:

# [ < { [ < } ] < { ] < } Collision? Example 
1  T  T  T  T   F  [ ] { } 
2  T  T  T  F   T  [ } { ] * 
3  T  T  F  T   T  [ { ] } 
4  T  T  F  F   T  [ { } ] 
5  T  F  T  T   T  ] } [ { * 
6  T  F  T  F   T  } [ ] { * 
7  T  F  F  T   Contradiction 
8  T  F  F  F   T  } [ { ] * 
9  F  T  T  T   T  ] { [ } * 
10  F  T  T  F   Contradiction 
11  F  T  F  T   T  { [ ] } 
12  F  T  F  F   T  { [ } ] 
13  F  F  T  T   T  ] { } [ * 
14  F  F  T  F   T  } ] { [ * 
15  F  F  F  T   T  { ] } [ * 
16  F  F  F  F   F  { } [ ] 

望着這真值表,找出衝突的最簡單的表達是:

NOT ([ < { AND [ < } AND ] < { AND ] < }) AND NOT ([ >= { AND [ >= } AND ] >= { AND ] >= })

但是我們知道,因爲{ < }[ < ],這減少到

NOT ([ < { AND ] < {) AND NOT ([ >= } AND ] >= })

對應於SQL:

WHERE NOT ('from' < $FROM and 'to' < $FROM) AND NOT ('from' > $TO and 'to' > $TO)(類似於@TiuTalk建議什麼的)。

但是,我們已經假定{ < }[ < ]。這很關鍵。查看真值表中標記爲*的行。在那些行中,或者是} < {或者] < [。我們知道這些不會發生。此外,有些行意味着完全矛盾的東西,如我們知道不可能的} < { AND { < }。消除所有這些行只給出6行:

# [ < { [ < } ] < { ] < } Collision? Example 
1  T  T  T  T   F  [ ] { } 
3  T  T  F  T   T  [ { ] } 
4  T  T  F  F   T  [ { } ] 
11  F  T  F  T   T  { [ ] } 
12  F  T  F  F   T  { [ } ] 
16  F  F  F  F   F  { } [ ] 

在這裏,我們可以看到,只有中間兩個子句決定是否有碰撞。即,([ < }) AND NOT (] < {)。這相當於([ < }) AND (] >= {)(否定第二個比較器),這相當於SQL WHERE ('from' < $TO AND 'to' >= $FROM)。這在語義上等同於保羅的條款(禁止通過<=到最後)。