sazmuelz Ответов: 3

Проверьте совпадение дат


 i have this date range: 2020-03-12 to 2020-03-13

and then i have the sql table with the following data:
RoomNumber  ReservationStartDate  ReservationEndDate
101	    2020-02-17	          2020-02-22
101	    2020-02-14	          2020-03-22
101	    2020-03-11	          2020-03-14
101	    2020-04-11	          2020-04-14



i want to insert this date range 2020-03-12 to 2020-03-13 into the table only if the dates do not overlap with any of the date ranges in the table. Any one who can help with the sql code to achieve that result?


Что я уже пробовал:

Я попробовал Решение ниже, но оно не работает
<pre>select COUNT(*) 
from ResTest
where roomNumber = 101 and
      ReservationTo > '2020-03-12' and
      ReservationFrom < '2020-03-13' 
	  insert into ResTest (RoomNumber, ReservationFrom , ReservationTo)
    select RoomNumber, resStartDate, resEndDate
    from (values (101, '2020-03-12', '2020-03-13')
         ) v(RoomNumber, resStartDate, resEndDate)
    where not exists (select 1
                      from ResTest
                      where ResTest.RoomNumber = v.RoomNumber and
                            ResTest.ReservationFrom > v.resStartDate and
                            ResTest.ReservationTo < v.resEndDate
                     )

3 Ответов

Рейтинг:
2

Richard Deeming

Два диапазона дат перекрываются тогда и только тогда, когда A.Start ≤ B.End и A.End ≥ B.Start.

Применяя это к вашему запросу:

DECLARE @RoomNumber int = 101;
DECLARE @NewReservationFrom date = '20200312';
DECLARE @NewReservationTo date = '20200313';

SELECT
    Count(1)
FROM
    ResTest
WHERE
    RoomNumber = @RoomNumber
And
    ReservationFrom <= @NewReservationTo
And
    ReservationTo >= @NewReservationFrom
;

If Not Exists
(
    SELECT 1 
    FROM ResTest 
    WHERE RoomNumber = @RoomNumber 
    And ReservationFrom <= @NewReservationTo 
    And ReservationTo >= @NewReservationFrom
)
BEGIN
    INSERT INTO ResTest (RoomNumber, ReservationFrom, ReservationTo)
    VALUES (@RoomNumber, @ReservationFrom, @ReservationTo);
END;


Рейтинг:
2

MarcusCole6833

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

Я поместил данные комнаты в инкрементную таблицу id'ED с датами, а затем проверил их все друг с другом

Затем я создаю таблицу конфликтов, показывающую, какой идентификатор конфликтует.



declare @roomdates table ( id int identity(1,1), roomid varchar(6) , fromD date , toD date, conflicted bit)
declare @tableConflict table( idA int ,idb int )

insert into @roomdates (roomid , fromd, toD , conflicted)
values('101', '2020-02-17','2020-02-22', 0)
insert into @roomdates (roomid , fromd, toD , conflicted)
values('101', '2020-02-14','2020-03-22', 0)
insert into @roomdates (roomid , fromd, toD , conflicted)
values('101', '2020-03-11','2020-03-14', 0)
insert into @roomdates (roomid , fromd, toD , conflicted)
values('101', ' 2020-04-11	',' 2020-04-14', 0)

select * from @roomdates

declare @min int = 0, @max int = 0

select @min = min(id) , @max = max(id) from @roomdates
declare @d1 date , @d2 date
while @min <= @max 
begin
	if @min = 500
	begin
		break
	end
	select @d1 = fromd , @d2 = toD from @roomdates where id = @min
	insert into @tableConflict
	select @min, id from @roomdates where @d1 >= fromD  and @d2 <= toD and id ! = @min
	select @min
set @min = @min + 1
end
select * from @tableConflict


Рейтинг:
0

OriginalGriff

Вам нужно немного подумать о своем запросе: он сложнее, чем вы допускаете.
Перекрытие может быть "с самого начала", "после конца", "внутри" или "снаружи":

Booked:       XXXXX
Start:      AAAAA
End:            BBBBB 
Inside:        CCC
Outside:    DDDDDDDDD
Единственное условие, которое вы можете вставить, - это когда новый период полностью находится снаружи:
Booked:       XXXXX
OK:      AAAAA
OK:                BBBBB
Поэтому начните с написания запроса, чтобы просто показать вам законные вставки, так как это намного проще: начало и конец до начала или начало и конец после конца.

Затем вы можете отменить это, чтобы очень легко выбрать незаконные перекрытия.