Проверьте интервал времени, используя условие SQL - PullRequest
2 голосов
/ 06 июля 2010

Я храню некоторые интервалы в 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 .: Мне нужно найти столкновенияпредупредить пользователя о том, что этот новый период уже существует или вступить в конфликт с существующим периодом.

Ответы [ 2 ]

3 голосов
/ 06 июля 2010

Я сталкивался с этим вопросом и просто хотел попытаться показать, как таблица истинности может идентифицировать сокращенную логику, которую Пол уже опубликовал.

Предположим, у вас есть интервал 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). Это семантически эквивалентно предложению Павла (за исключением работы через <= до конца).

2 голосов
/ 06 июля 2010
WHERE ($TO >= `from` AND $FROM <= `to`)

Обратите внимание, что это работает для случая, когда новый диапазон перекрывает весь диапазон, когда он только частично перекрывает и когда он также охватывает его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...