Запросы базы данных, как правило, такие простые, но иногда такие сложные. (мозговой тренер)Получение Недоступных дат для аренды продукта с запасами
У меня есть продукты, акции и rentStockOrders. Эти продукты можно взять напрокат в течение нескольких дней. У запасов также есть дата, когда они доступны. Если новый продукт (запас) может быть арендован, зависит от уже арендованных запасов этого продукта.
- Товар не может быть арендован перед его доступной датой.
- A rentStockOrder (между заказом и запасами) содержит заказы, таким образом
rentStartDate
иrentEndDate
. - Продукт можно взять напрокат за несколько дней, если дата начала не указана. Продукт выбирается, и после этого выбирается дата выбора времени, чтобы выбрать день начала аренды.
- Прилагается общая минимальная и максимальная дата (примерно на год вперед).
Идея заключается в том, что пользователь не выбрал дату начала еще до того, как пользователь может делать, что я хочу, чтобы отключить некоторые даты в DateTimePicker, которые не могут быть использованы в качестве даты начала, поскольку нет запасов доступный для периода аренды продукта.
Чтобы выразить это в контексте: выбран один продукт, пользователю предоставляется возможность указать длину в днях, которые он хочет взять в аренду для этого продукта (1 неделя, 2 недели или 3 недели). Когда пользователь выбрал это, они должны выбрать дату начала. Вместо того, чтобы каждый раз показывать ошибку, что эта дата недоступна, я скорее отключу даты начала до начала.
Поскольку чаще всего продукт можно арендовать, а затем нет, я думаю, что лучше отправить список отсутствующих выбранных дат на мой сайт, а не весь список доступных дат. Таким образом, дни, которые недоступны, не могут быть нажаты на дату выбора времени.
Большинство примеров, которые я нашел до сих пор, включают входной параметр для даты начала и окончания, которого у меня нет, все, что у меня есть в течение нескольких дней, когда продукт хочет арендовать и сколько акций уже сдано в аренду на определенное время кадры.
EDIT:
В соответствии с просьбой, тестовые данные и таблицы:
Акции
+---------+-----------+-------------------+
| stockId | productId | availableFromDate |
+---------+-----------+-------------------+
| 1 | 1 | 1-01-2016 |
| 2 | 1 | 1-01-2016 |
+---------+-----------+-------------------+
RentStockOrders
+------------------+---------+----------------+----------------+
| rentStockOrderId | stockId | beginRentDate | endRentDate |
+------------------+---------+----------------+----------------+
| 1 | 1 | 15-1-2016 | 14-2-2016 |
| 2 | 2 | 30-1-2016 | 20-2-2016 |
| 3 | 2 | 26-2-2016 | 7-3-2016 |
| 4 | 1 | 29-2-2016 | 14-3-2016 |
+------------------+---------+----------------+----------------+
На основании этих записей я хочу сгенерировать список недоступен. Для упрощения я выделил несколько столбцов
Ввод - это день и продукт. Так что, если я был бы вход для дней: 14 и ProductID: 1 я бы некоторые из нижеследующих ожидаемых результатов:
- 25-01-2016 (stockId 1 уже забронированы, и акции 2 получает желтую карточку в ближайшее время, 14 дней не представляется возможным.
- 30-01-2016 (как предупреждение)
- 13-02-2016 (шток 1 еще не вернулся)
- 17-02-2016 (приклад 2 уже забронированы , запас 1 будет арендован за 13 дней, этого недостаточно для 14).
- .. и намного больше, где обе акции уже сданы в аренду.
Чего я бы не ожидал, например, 15-02-2016, потому что запас 1 будет доступен в течение следующих 14 дней.
Если это сложно, возможно, получение доступных дат проще, и я переключу это на код. В этом примере из базы данных будет меньше данных, но на самом деле существует около 250 единиц одного продукта, поэтому, возможно, лучше получить недоступные даты.
Я пробовал this answer, чтобы получить доступные даты, без успеха, без ошибок, просто не возвращает данных.
declare @startDate datetime, @endDate datetime, @days int
select @startDate = '2016/01/01', @endDate='2016/03/31', @days=2
select stockId, min(endRentDate)
from
(
select stockId ,endRentDate,
(select top 1 endRentDate
from RentStockOrders sInner
where sInner.endRentDate > sOuter.beginRentDate
and sInner.stockId = sOuter.stockId
and sInner.endRentDate between @startDate and @endDate
order by sInner.endRentDate) as nextAvailableDate
from RentStockOrders sOuter
where sOuter.beginRentDate between @startDate and @endDate
) sub
group by stockId, nextAvailableDate
having dateDiff(d, min(endRentDate), isNull(nextAvailableDate,dateAdd(d,1,@endDate))) >= @days
[Вредные привычки пинать: использование старого стиля JOIN и] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old -style-joins.aspx) - стиль старого стиля * разделенный запятыми список таблиц * был заменен на * правильный * ANSI 'JOIN' синтаксис в ANSI - ** 92 ** SQL Standard (** более 20 лет ** назад), и его использование обескуражено –
Хорошо, спасибо за это, всегда было интересно, почему .. Получил решение для этого вопроса? :) – CularBytes
Справа возникает связанный с этим вопрос: http://stackoverflow.com/questions/15796846/fnd-consecutive-dates-withing-a-defined-span-where-a-trainer-is-available-to- sch? rq = 1 – Turophile