使用SQL条件检查时间间隔

发布于 2024-09-08 13:03:35 字数 720 浏览 12 评论 0原文

我在 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)

观察:我需要找到冲突来提醒用户这个新时期已经存在或与现有时期发生冲突。

I'm storing some intervals in the SQL, example:

id INT
from DATE
to DATE

How can I check, using only one condition (if possible) if a NEW interval conflict with a existing one?

Examples:

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

Every interval (in the first three) has some conflict with the other two intervals... Except the last one that's alone.

--

This check can be achieved using some condition like:

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

But this only check intervals that contains the new one... Not the other intervals that has some intersections OR the ones that's inside the new one.

Maybe something like this?

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

Obs.: I need to find the collisions to alert the user that this new period already exist or get in conflict with an existin one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七颜 2024-09-15 13:03:35

我遇到了这个问题,只是想尝试展示真值表如何识别保罗已经发布的简化逻辑。

假设您有一个从 [ 到 ] 的区间,您想要对照从 { 到 } 进行检查。

这转化为以下真值表:

 #   [ < {   [ < }   ] < {   ] < }    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:

< code>WHERE NOT ('from' < $FROM and 'to' < $FROM ) AND NOT ('from' > $TO and 'to' > $TO) (类似于 @TiuTalk建议)。

然而,我们已经假设 { < }[ < ]。这很关键。查看真值表中标记为 * 的行。在这些行中,} < {] < [。我们知道这些不会发生。另外,有些行暗示着完全矛盾的事情,例如 } < { 和 { < } 我们知道这是不可能的。消除所有这些行仅得到 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 的子句(除非将 <= 处理到最后)。

I came across this question and just wanted to try to show how a truth table can identify the reduced logic that Paul already posted.

Assume you have an interval from [ to ] that you want to check against from { to }.

This translates to the following truth table:

 #   [ < {   [ < }   ] < {   ] < }    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       { } [ ]

Looking at this truth table, the simplest expression to identify collisions is:

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

However we know that, since { < } and [ < ], this reduces to

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

Which corresponds to the SQL:

WHERE NOT ('from' < $FROM and 'to' < $FROM ) AND NOT ('from' > $TO and 'to' > $TO) (similar to what @TiuTalk suggested).

However, we have already assumed that { < } and [ < ]. This is critical. Look at the rows marked * in the truth table. In those rows, either } < { or ] < [. We know those won't happen. Plus, some rows imply completely contradictory things like } < { AND { < } which we know to be impossible. Eliminating all these rows gives just 6 rows:

 #   [ < {   [ < }   ] < {   ] < }    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       { } [ ]

Here, we can see that just the middle two clauses determine whether there's a collision. Namely, ( [ < } ) AND NOT ( ] < { ). This is equivalent to ( [ < } ) AND ( ] >= { ) (negating the second comparator) which is equivalent to the SQL WHERE ('from' < $TO AND 'to' >= $FROM). This is semantically equivalent to Paul's clause (barring working through the <= to the end).

只涨不跌 2024-09-15 13:03:35
WHERE ($TO >= `from` AND $FROM <= `to`)

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

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

Note this works for the case where the new range overlaps the whole range, when it only partially overlaps and when it encompasses it as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文