我在 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)
观察:我需要找到冲突来提醒用户这个新周期已经存在或与现有周期发生冲突。
最佳答案
我遇到了这个问题,只是想尝试展示真值表如何识别 Paul 已经发布的简化逻辑。
假设您有一个间隔 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)
。这在语义上等同于 Paul 的子句(除非从 <=
一直工作到最后)。
关于sql - 使用SQL条件检查时间间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3188963/