#sql #sql-server #tsql #where-clause
#sql #sql-сервер #tsql #where-предложение
Вопрос:
У меня есть простой запрос ниже, чтобы выбрать доступные активы из таблицы на основе их оформления заказа и ожидаемой даты возврата. Если проверка и ожидаемая дата возврата совпадают с @RentStartDate
, а @RentEndDate
затем я хочу выбрать его как UnavailableAsset
. Пожалуйста, ознакомьтесь с моим запросом ниже
set @RentStartDate = '2016-10-13';
set @RentEndDate = '2016-10-18';
SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (CheckOutDate >= @RentStartDate AND CheckOutDate <= @RentEndDate)
OR
(ExpectedReturnDate >= @RentStartDate AND ExpectedReturnDate <= @RentEndDate)
OR
(@RentStartDate >= CheckOutDate AND @RentEndDate <= ExpectedReturnDate);
Теперь я знаю, что этот запрос работает отлично, но я просто не уверен, есть ли лучший способ написать условия в where
предложении.
Есть ли лучший способ упростить условия, чтобы сделать этот запрос более эффективным?
Спасибо
Комментарии:
1. Какой движок базы данных? Вы проверили план запроса, чтобы узнать, что он делает?
2. Определение таблицы, включая индексы и т.д.?
3. Хотя, скорее всего, это не дает лучшей производительности, но улучшает читаемость, вы могли бы заменить
(CheckOutDate >= @RentStartDate AND CheckOutDate <= @RentEndDate)
наCheckOutDate BETWEEN @RentStartDate AND @RentEndDate
и(ExpectedReturnDate >= @RentStartDate AND ExpectedReturnDate <= @RentEndDate)
наExpectedReturnDate BETWEEN @RentStartDate AND @RentEndDate
.4. Добавлен
sql-server
тег на основе используемого синтаксиса
Ответ №1:
Основываясь на описании того, что вы делаете, я не понимаю, почему вы считаете, что ваш запрос работает.
Запрос перекрытия должен выглядеть следующим образом:
SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE CheckOutDate <= @RentEndDate AND
ExpectedReturnDate >= @RentStartDate;
Этот тип запросов может быть сложно оптимизировать (в большинстве баз данных). Вы можете начать с индекса на agreementasset(CheckOutDate, ExpectedReturnDate, AssetID)
.
Комментарии:
1. Я уже пробовал этот запрос раньше. Он выбирает только тот ресурс, который имеет как checkout, так и expectedReturndate, попадающие в диапазон дат аренды. Что я имел в виду под перекрытием, так это то, что даже если проверка или ожидаемый возврат попадают в диапазон даты аренды, этот ресурс будет недоступен
2. Похоже, что индексирование — это правильный путь.
3. @Vibol. . . Внимательно прочитайте запрос. Это логика для любого перекрытия периодов времени.
Ответ №2:
Вы пробовали использовать BETWEEN
ключевое слово?
SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (CheckOutDate BETWEEN @RentStartDate AND @RentEndDate)
OR (ExpectedReturnDate BETWEEN @RentStartDate AND @RentEndDate)
Комментарии:
1. Вы забыли включить последнее
OR (@RentStartDate >= CheckOutDate AND @RentEndDate <= ExpectedReturnDate)
. Этот случай не распространяется на ваши предикаты. (По крайней мере, если у вас нет более глубокого понимания предполагаемой логики предикатов.)
Ответ №3:
Я не думаю, что вы можете упростить и не дублировать условия
SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (@RentStartDate <= CheckOutDate AND @RentEndDate >= CheckOutDate)
OR (@RentStartDate >= CheckOutDate AND @RentEndDate <= ExpectedReturnDate)
OR (@RentStartDate <= ExpectedReturnDate AND @RentEndDate >= ExpectedReturnDate);