2

我在 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.:我需要找到冲突以提醒用户这个新时期已经存在或与现有时期发生冲突。

4

2 回答 2

3

我遇到了这个问题,只是想尝试展示真值表如何识别 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)。这在语义上等价于保罗的条款(除非一直工作<=到最后)。

于 2010-07-06T19:56:30.867 回答
2
WHERE ($TO >= `from` AND $FROM <= `to`)

请注意,这适用于新范围与整个范围重叠、仅部分重叠以及包含它的情况。

于 2010-07-06T18:14:35.547 回答