Проверьте, перекрывается ли график между днями - PullRequest
0 голосов
/ 11 мая 2011

Мне нужно выяснить, перекрывает ли новое расписание какие-либо из существующих расписаний.

Это таблица "интервалов":

     id  first              last    
     1   1900-01-01 09:00   1900-01-01 10:00
     2   1900-01-01 15:00   1900-01-01 18:00
     3   1900-01-01 18:01   1900-01-01 08:00

Я использую скалярную функцию dbo.TimeOnly для извлечения части времени из полей даты и времени.

Мои критерии выбора следующие

Первый случай

     declare @start datetime
     declare @end datetime

     set @start = dbo.TimeOnly('2011-may-11 08:01:00');
     set @end = dbo.TimeOnly('2011-may-11 15:30:00');

     select  * from intervals where 
     ( NOT ( dbo.TimeOnly(last) < @start OR  @end < dbo.TimeOnly(first) ) )

Это вернет 1 и 2 записи. Я получил эту логику от Проверьте, перекрывает ли расписание друг друга?

Второй случай

    set @start = dbo.TimeOnly('2011-may-11 07:01:00');
    set @end = dbo.TimeOnly('2011-may-11 08:30:00');

Как мне написать запрос, который будет возвращать только 3-ю запись для критериев во втором случае?

UPDATE

Я дам более подробную информацию по моей проблеме

Разные люди управляют определенным событием в течение определенного времени в течение дня.

Для Понедельник формат расписания выглядит следующим образом

    Id  Start       End          User   Days    
     1  00:01 AM    08:00 AM     'A'    1
     2  08:01 AM    04:00 PM     'B'    1
     3  04:00 PM    00:00 AM     'C'    1

Для Вторник

     4  08:01 AM    04:00 PM     'B'    2
     5  07:00 PM    07:00 AM     'C'    2

Для Среды

     6  08:01 AM    04:00 PM     'A'    4
     7  10:00 PM    08:00 AM     'B'    4

Здесь дни хранятся в формате битовых значений, т.е.

Понедельник = 1, вторник = 2, среда = 4, четверг = 8, пятница = 16, суббота = 32 и воскресенье = 64

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

Для определенного времени события ( Скажите, что даже произошло в 04:00 AM во вторник ) Я хотел бы найти правильное расписание (будет "5"), которое находится между временем начала и окончания .

Ответы [ 2 ]

0 голосов
/ 11 мая 2011

Измените свой SELECT на это:

select  * from intervals where 
(
( dbo.TimeOnly(last) > dbo.TimeOnly(first)
AND
NOT (dbo.TimeOnly(last) < @start OR  @end < dbo.TimeOnly(first)) )

OR

( dbo.TimeOnly(last) < dbo.TimeOnly(first)
AND
( @start >= dbo.TimeOnly(first) OR @end <= dbo.TimeOnly(last) OR (@start < dbo.TimeOnly(first) AND @end > dbo.TimeOnly(last)) ) )
)

Возможно, я где-то пропустил скобки, но надеюсь, что нет.

Концепция здесь - это запрос с двумя основными группировками в сочетании сИЛИ.Первое предложение проверяет интервалы, где last> first , и является в основном копией существующего запроса с добавлением условия last> first , в то время как второе предложение проверяет интервалы, где last .

В случае, когда last

  • начало - после первого интервала
  • конец предшествует последнему интервалу
  • начало и конец полностью охватывают интервал, т. Е. Начало предшествует первому, а конец - последнему

Любое из этих трех условий будет означатьрасписание для проверки находится в пределах существующего интервала, поэтому 3 условия объединяются с ИЛИ.

0 голосов
/ 11 мая 2011

Вам нужно будет сделать что-то вроде этого:

Declare @start datetime
Declare @duration int

Set @start = dbo.TimeOnly('2011-May-11 07:01:00');
-- Get the number of minutes in your timespan
Set @duration = DateDiff(minute, '2011-May-11 07:01:00', '2011-May-12 08:30:00');

Select id, first, last
From intervals
Where (DateDiff(minute, dbo.TimeOnly(first)), @start) + @duration) > 0
AND DateDiff(minute, dbo.TimeOnly(first), @start) <
 DateDiff(minute, dbo.TimeOnly(first), dbo.TimeOnly(last));

Предполагая, что ваша dbo.TimeOnly функция, по сути, такая же, как Convert(time, {timefield}).

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

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

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