2012-03-10 5 views
0

нормально, так что я пытаюсь выбрать строки из БД, чтобы увидеть, если есть какие-либо столкновения внутри календаря, и я наткнулся на еще один вопросSQL заявления выборе строк

вот мой код

$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), тогда выберите строку в противном случае: кадрируйте как верхнюю границу.

я, хотя я был почти сразу же с тем, что я был тем не менее пытаюсь этой части

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

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

+0

Извините, но в чем ваш вопрос? – Ben

ответ

2

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

Есть целый ряд вопросов, касающиеся SO (включая Determining whether two date ranges overlap), которые имеют дело с перекрытием периодов времени, но основной метод для определения два периодов, обозначаемых [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 

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

+0

Спасибо, что ты отлично справился, снова застрял над мыслящими вещами, когда, как правило, очень простой ответ! – Ash

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