Мне нужно внедрить систему бронирования залов, и есть требование, чтобы получить бесплатные залы на основе забронированных FromDateTime
до ToDateTime
Стол заказов
HallID FromDateTime ToDateTime
1 2018-01-01 03:00:00 2018-01-01 05:00:00
2 2018-01-01 06:30:00 2018-01-01 12:00:00
3 2018-01-01 13:00:00 2018-01-01 15:15:00
Пользователь должен иметь возможность ввести от FromDateTime
до ToDateTime
, чтобы проверить, есть ли запись в таблице заказов. Если существует, зал не доступен для бронирования.
Тестовые сценарии: входы
FromDateTime ToDateTime Result
2018-01-01 03:00:00 2018-01-01 05:00:00 : Hall not available
2018-01-01 08:45:00 2018-01-01 10:30:00 : Hall not available (This time is between Hall ID 2s booking time)
2018-01-01 15:30:00 2018-01-01 18:00:00 : Hall available
Вопрос
Можно ли использовать в этом сценарии предложение между FromDateTime
и ToDateTime
для решения этой проблемы?
Я не смог найти способ использовать между ними, поэтому я использовал метод ниже. Но его стоимость очень высока.
-- Selecting all the records related to perticular product(hall) in to a temp table.
DECLARE @TempOrderDateTime TABLE (FromDateTime DATETIME,ToDateTime DATETIME)
INSERT INTO @TempOrderDateTime
SELECT FromDateTime,ToDateTime
FROM [Order].[Order]
WHERE ProductID = 7
Разделение каждой записи на 1-часовые зелья и сохранение внутри временной таблицы. Это создает другую проблему.
Проблема в том, что если я использую 1-часовой сегмент, алгоритм не сможет работать с записями, которые имеют минуты в FromDateTime или ToDateTime
DECLARE @ProdTimes TABLE (Dates DATETIME)
DECLARE @PRowCount INT = (SELECT COUNT(*) FROM @TempOrderDateTime)
WHILE(@PRowCount>0)
BEGIN
DECLARE @TopFromDateTime DATETIME = (SELECT TOP(1)FromDateTime FROM
@TempOrderDateTime)
DECLARE @TopToDateTime DATETIME = (SELECT TOP(1)ToDateTime FROM @TempOrderDateTime)
;WITH Dates_CTE
AS (SELECT @TopFromDateTime AS Dates
UNION ALL
SELECT DATEADD(HOUR, 1, Dates)
FROM Dates_CTE
WHERE Dates < @TopToDateTime)
INSERT INTO @ProdTimes
SELECT Dates
FROM Dates_CTE AS t
OPTION (MAXRECURSION 0);
DELETE TOP(1) FROM @TempOrderDateTime
SET @PRowCount = (SELECT COUNT(*) FROM @TempOrderDateTime)
END
Здесь я даюFromDateTime и ToDateTime в качестве входных данных для проверки доступности.
DECLARE @FromDateTime DATETIME = '2018-06-01 12:00:00.000'
DECLARE @ToDateTime DATETIME = '2018-06-01 14:00:00.000'
DECLARE @PTimes TABLE (Dates DateTime)
;WITH Dates_CTE
AS (SELECT @FromDateTime AS Dates
UNION ALL
SELECT DATEADD(HOUR, 1, Dates)
FROM Dates_CTE
WHERE Dates < @ToDateTime)
INSERT INTO @PTimes
SELECT *
FROM Dates_CTE AS t
OPTION (MAXRECURSION 0);
DELETE FROM @PTimes WHERE Dates = @FromDateTime OR Dates = @ToDateTime
Наконец, выполните следующую операцию для сопоставления таблиц. Если записи не найдены, зал доступен для бронирования.
SELECT * FROM @PTimes p
WHERE EXISTS (SELECT 1 FROM @ProdTimes pt WHERE p.Dates = pt.Dates)
Мой подход в настоящее время применим. Но главный недостаток -
- Если записи таблицы заказов содержат запись с минутами, алгоритм не будет работать. Потому что он отфильтровывает только 1-часовые зелья.
- Стоимость очень высокая.
Пожалуйста, предложите мне правильный способ решения этой проблемы.
Заранее спасибо.