代码之家  ›  专栏  ›  技术社区  ›  Thiago Belem

使用SQL条件检查时间间隔

  •  2
  • Thiago Belem  · 技术社区  · 15 年前

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

    2 回复  |  直到 15 年前
        1
  •  2
  •   Paul Tomblin    15 年前
    WHERE ($TO >= `from` AND $FROM <= `to`)
    

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

        2
  •  3
  •   Mark Peters    15 年前

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

    假设你有一个时间间隔 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) <= 最后)。

    推荐文章