Операторы SQL, выбирающие строки - PullRequest
0 голосов
/ 11 марта 2012

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

вот мой код

$query3 = $dbh->prepare("SELECT * FROM calendar_" . $companyID . " WHERE (calTime+duration) > :calstart AND (calTime+duration) <= (:calend + (duration-(:calend-calTime))) AND agentID = :agentID ORDER BY calTime ASC");
$query3->bindParam(':calstart', $time);
$calend = $time + $duration;
$query3->bindParam(':calend', $calend);

, который выглядит примерно так в более читаемом SQL

  SELECT * FROM calendar_01 WHERE (calTime + duration) > 1331386200 
  AND (calTime + duration) <= ( 1331388000 + ( duration - ( 1331388000 - calTime ) ) )
  AND agentID =1
  ORDER BY calTime ASC
  LIMIT 0 , 30

нижняя граница, очевидно, работает нормально, однако с верхней границей у меня возникает проблема, когда, если продолжительность события составляет 7200 2 часа, и кто-то пытается ввести новое событие, которое, скажем, только 1800, и начинается через 1800 после первого позволит это, даже если введенное событие имеет длину 7200 и фактически перекрывает новое событие. Поэтому мне нужно, чтобы верхняя граница была динамической в ​​том смысле, что если: calend <(calTime + duration), тогда выберите строку, в противном случае используйте: calend в качестве верхней границы. </p>

Я, хотя я был почти прав в том, что я пытался, однако, эта часть

  ( 1331388000 + ( duration - ( 1331388000 - calTime ) ) )

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

1 Ответ

2 голосов
/ 11 марта 2012

Похоже, вы ищете, перекрывает ли новая запись какую-либо существующую. Новая запись определяется временем начала (1331386200 в вашем примере) и продолжительностью (1800, выведено из комментария и 1331386200 + 1800 = 1331388000).

Существует ряд вопросов по SO (включая Определение того, перекрываются ли два диапазона дат ), которые касаются перекрывающихся периодов времени, но основной метод определения того, являются ли два периода обозначенными [s1, e1] и [e2, s2] перекрытие просто:

if (s1 < e2 && s2 < e1)
    ...the intervals overlap...

Вы можете манипулировать с < против <=, если вам нужно. Конечно, вы можете добавлять дополнительные критерии к вашему запросу по мере необходимости.

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

-- s1 == calTime
-- e1 == calTime + duration
-- s2 == 1331386200
-- e2 == 1331388000

SELECT *
 FROM calendar_01
WHERE calTime    < 1331388000            -- s1 < e2
  AND 1331386200 < (calTime + duration)  -- s2 < e1
  AND agentID = 1                        -- other criteria
ORDER BY calTime ASC
LIMIT 0 , 30

Если это возвращает какие-либо данные, то возникает конфликт между новыми данными и одной или несколькими существующими строками данных (оператор возвратит список до 30 первых таких строк).

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