2013-05-01 5 views
2

Таблица имеет ценуValidFrom, PriceValidTo, BookingWindowFrom и BookingWindowДля полей даты и поля валюты цены. Клиент вставляет или обновляет строки случайным образом. Некоторые строки могут иметь период PriceValid короче, чем другие, но могут быть в том же месяце (и с другой ценой), например. Другие строки могут иметь одинаковые периоды PriceValid, но могут отличаться только в периоде бронирования. Стол никогда не очищается, и все приемлемо. Мне нужен запрос, который, учитывая дату, вернет цену из строки с наивысшей ценой PriceValidFrom. В приведенном ниже примере, рассматривая таблицу и оператор запроса:выберите верхний ряд, используя две разные даты:

PriceValidFrom PriceValidTo Price 
05/01/2013  05/30/2013 $100.00 
05/15/2013  05/20/2013 $50.00 

псевдо SQL

select top 1 price 
where :Date between PriceValidFrom and PriceValidTo 
order by PriceValidFrom DESC, Price 

Если дата 05/16/2013 запрос возвращает $ 50,00, как и ожидалось.

Теперь, пользователь должен добавить период бронирования окна, которые также должны взять на себя самую высокую BookingWindowFrom:

PriceValidFrom PriceValidTo Price  BookingWindowFrom BookingWindowTo 
05/01/2013  05/30/2013 $100.00 4/1/2013   5/30/2013 
05/15/2013  05/20/2013 $50.00 4/1/2013   5/30/2013 
05/15/2013  05/20/2013 $75.00 5/1/2013   5/30/2013 

Теперь, если дата 05/16/2013 и дата бронирования 5/1/2013 запрос должен вернуть $ 75,00

Как достичь ожидаемого результата? Обратите внимание, что это упрощенный пример, но в реальной таблице будет сотни строк.

select top 1 price 
where :Date between PriceValidFrom and PriceValidTo  
    and :BookingDate between BookingWindowFrom and BookingWindowTo 
+0

Что датируется временем ovverides? Действителен до? –

+0

Некоторые данные описания или примера, показывающие, что делать, когда EffectiveDate существует и не существует, было бы полезно. –

+0

Я обновил свой пост. Пожалуйста, взгляните на это еще раз. Спасибо –

ответ

1

ORDER BY это не решение, вы должны изменить свое положение WHERE. Например:

SELECT top 1 price  
WHERE EffectiveDate = :pDate 
    OR (EffectiveDate IS NULL AND :pDate BETWEEN ValidFrom AND ValidTo) 

ORDER BY EffectiveDate DESC, ValidFrom DESC, Price 

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

1

Это предположение основано на том, как я думаю, вы хотите EffectiveDate использовали:

select top 1 price 
where :pDate between coalesce(EffectiveDate, ValidFrom) and ValidTo 
order by coalesce(EffectiveDate, ValidFrom) DESC, Price 

Или вы хотите, чтобы просто выбросить даты все ValidXXX если есть EffectiveDate в наличии?

Я бы предложил использовать функции min/max или rank, чтобы получить цену, а не умело манипулировать не ANSI top с предложением, но это всего лишь мнение.

Должен признать, что этот EffectiveDate кажется немного взломанным на первый взгляд, чтобы не очищать ValidFrom/To даты должным образом, например: «Мы не хотим тратить время на исправление наших данных, просто сделайте это эта цена прямо сейчас! " Таким образом, что останавливает EffectiveDates от слишком большого количества и заставляет казаться, что вам нужно добавить столбец ReallyEffectiveDate? Слова «Действительный» и «Эффективный» здесь кажутся синонимами и могут быть очень запутанными для понимания и программирования. Ладно, допрос заполнен.

+0

Ваши предположения на 100% правильны. Я обновил свой пост, пожалуйста, взгляните на него еще раз. Благодарю. –

Смежные вопросы