2011-06-29 2 views
2

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

У меня есть таблица MySQL с 3 столбцами, date - startTime - finishTime. Дата представляет собой поле типа «дата» MySQL, а время начала и окончания - это поля типа «время».

Скажем, например, у меня есть запись в базе данных, как показано ниже, позволяет называть этот сеанс 1;

date = 2011-06-30, startTime = 09:00:00, finishTime = 11:00:00 

Если я пришел, чтобы добавить еще одну сессию, мне нужно убедиться, что она не конфликтует с существующим сеансом. Таким образом, следующее будет терпеть неудачу, потому что оно попадает в промежуток между сеансом 1 и временем окончания.

date = 2011-06-30, startTime = 10:00:00, finishTime = 12:00:00 

Таким образом, запись может быть вставлена ​​только «ПОСЛЕ» или «ПЕРЕД» существующей сессии.

Я использую PHP/MySQL, и я исхожу на основе того, что запрос может быть запущен, и если есть «соответствующие результаты», то сбой, если есть «arent» соответствующие результаты, затем вставьте.

Заранее спасибо.

+1

гм ... что это вопрос? – ianbarker

+0

И что происходит, когда есть сеанс с 09:00 - 11:00, а новый - с 11:00 до 13:00. Столкновение или нет? –

+0

@ypercube Нет столкновения. – Rob

ответ

4

Я использую PHP/MySQL, и я основываюсь на том, что запрос может быть запущен, и если есть «соответствующие результаты», то не удастся, если есть «arent» соответствующие результаты, затем вставьте.

Ну, попробуйте это. Здесь :date: - дата ввода, которую вы собираетесь добавить, и :start-time: и :finish-time: - это время начала и окончания соответственно.

SELECT EXISTS (
    SELECT 
     1 
    FROM 
     TableName 
    WHERE 
     `date` = :date: AND 
     (:start-time: BETWEEN startTime AND finishTime OR 
      :finish-time: BETWEEN startTime AND finishTime OR 
      startTime BETWEEN :start-time: AND :finish-time: 
     ) 
) AS `Clash` 
+0

Работает отлично! Огромное спасибо! – Rob

+0

Я только что понял, что это сообщает о столкновении, если оба сеанса столкнулись только на своих конечных точках (т. Е. Конечная точка одного - это начало другого). Возможно, это не так. Это происходит потому, что 'BETWEEN' является всеобъемлющим. Запрос может быть переписан, чтобы исключить использование 'BETWEEN' в пользу операторов строгого сравнения' <' and '> '. – Hammerite

+0

@Hammerite: Точно. 'x BETWEEN a AND b', его следует заменить на' a <= x AND x

0

Я бы структурировал таблицу по-другому. У меня было бы две колонки, как datetime, так и имена session_start и session_end.

Логика: вы не можете вставить новую сессию, если это session_start время не > или <, чем старая сессия session_end.

0

Предполагая, что $ дата, $ и $ начальный промежуток finishTime ваши PHP переменные, хранящие дату, время начала и окончания времени, соответственно, должен быть вставлен.

$query = 'INSERT INTO `session` 
SELECT \'' . $date . '\', \'' . $startTime . '\', \'' . $finishTime . '\' 
FROM `session` 
WHERE NOT EXISTS (SELECT * 
    FROM `session` 
    WHERE `date` = \'' . $date . '\' 
    AND \'' . $startTime . '\' BETWEEN `startTime` and `finishTime` 
)'; 

Надеюсь, это поможет.

+0

Что делать, если время начала нового сеанса не находится между временем начала и окончания текущего сеанса, но его время окончания? – Hammerite

+0

Тогда он должен «потерпеть неудачу». – Rob

+0

Да, мой плохой я пропустил, чтобы добавить эти условия. Спасибо, что указали их – Abhay

0

Я хотел бы использовать простой:

INSERT INTO session 
    (`date`, startTime, finishTime) 
    SELECT 
    ($date, $startTime, $finishTime) 
    WHERE NOT EXISTS 
    (SELECT 
      * 
     FROM 
      session 
     WHERE 
      `date` = $date 
     AND $startTime < finishTime 
     AND startTime < $finishTime 

    ) 

< должен быть изменен на <=, если вы хотите два периода 09:00 - 11:00 и 11:00 - 13:00 к конфликтовать.

1

Я столкнулся с этой проблемой дата перекрытием обнаружения, моя первая мысль была сделать что-то подобное решение Hammerite, но я нашел, что это решение неполными главным образом потому, что слишком много возможных сценариев, в которых два диапазона дат может быть в конфликте:

запрос я в конечном итоге, используя для решения этой проблемы было что-то вроде:

/* overlapping dates */ 
SELECT * 
FROM my_table 
WHERE `date` = $date AND 
    NOT (
    `start_time` < $start_time and `finish_time` < $start_time 
    OR 
    `start_time` > $end_time and `finish_time` > $end_time 
) 

для получения более подробной информации вы можете check my blog here

Смежные вопросы