Запрос: Рассчитать среднюю стоимость проживания в зависимости от даты - PullRequest
4 голосов
/ 14 мая 2011

periods

Привет всем,

Мне нужно создать запрос для поиска дома, который бы соответствовал введенным пользователем данным в базе данных: дата, когда они хотят переместиться и уйти,количество людей в группе и цена за ночь.

Допустим, пользователь искал дом:

даты: с 2011-01-15 по 2011-03-01 (см. Период A1C1), для 3 человек, и он готов тратить от 90 до 125 долларов за ночь.

Это мои ручные вычисления для этого поиска:

  • даты доступны в базе данных
  • общее количество дат, которые пользователь хочет остаться: 44 дня
  • цена за первый период 2011-01-15 до 2011-01-25 - 10 дней * 100 долл. США = 1000
  • цена за второй период с 2011-01-25 по 2011-02-14 - 20 дней * 120 долл. США = 2400
  • цена за третий период 2011-С 02-14 по 2011-03-01 составляет 14 дней * 140 долларов США = 1960 долларов
  • общая средняя цена за ночь = 1000 + 2400 + 1960/44 = 121,8
  • ценыe и количество людей соответствует вводу пользователя, поэтому мы отображаем этот дом

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

У меня такой вопрос: Как должен выглядеть мой запрос для быстрого расчета, если пользовательские данные соответствуют записям в базе данных .

Я думал об использовании функции SQL DATEDIFF и затем умножил нацена ... и т. д., но это выглядит для меня довольно сложно.

Буду признателен за любой совет.

Спасибо

ОБНОВЛЕНИЕ

Вот моя база данныхсхема:

Таблица "apt_search_periods", в которой хранятся все объединенные даты (непрерывные даты из таблицы доступности)

+-----------+------------+------------+-----------+--------------+--------+
| period_id | start_date | end_date   | rental_id | nb_of_people | merged |
+-----------+------------+------------+-----------+--------------+--------+
|        21 | 2011-03-31 | 2012-03-31 |       548 |            4 | y      |
+-----------+------------+------------+-----------+--------------+--------+

Таблица "apt_search_periods_avail", связывающая объединенные даты с таблицей доступности

+----+-----------+-----------------+
| id | period_id | availability_id |
+----+-----------+-----------------+
| 21 |        21 |           20953 |
| 22 |        21 |           20952 |
| 23 |        21 |            4033 |
+----+-----------+-----------------+

Таблица «Наличие» с расширенными датами и ценами

+-------+-----------+------------+------------+--------------+--------------+
| id    | rental_id | start_date | end_date   | nb_of_people | rent_per_day |
+-------+-----------+------------+------------+--------------+--------------+
| 20952 |       548 | 2011-03-31 | 2011-07-01 |            4 |          575 |
|  4033 |       548 | 2011-07-01 | 2011-09-01 |            4 |          680 |
| 20953 |       548 | 2011-09-01 | 2012-03-31 |            4 |          575 |
+-------+-----------+------------+------------+--------------+--------------+

1 Ответ

2 голосов
/ 14 мая 2011

Следующие должны начать.

Обратите внимание, что единственная разница состоит в том, что третий период составляет 15 дней и 14 в соответствии с DATEDIFF.

Оператор SQL

;WITH q AS (
  /* Kick of with the record where startdate < input < enddate */
  SELECT  date_start
          , date_end
  FROM    @HouseSearch
  WHERE   date_start <= @date_start
          AND date_end >= @date_start
          AND nb_people >= @nb_people -- Only when number of people is adequate
  UNION ALL
  SELECT  q.date_start
          , hs.date_end
  FROM    q
          INNER JOIN @HouseSearch hs ON hs.date_start = q.date_end
  WHERE   nb_people >= @nb_people -- Only when number of people is adequate
)
SELECT  *
FROM    (
          -- Only return result if sequence exists between date range
          SELECT  date_start = MIN(date_start)
                  , date_end = MAX(date_end)
          FROM    q
          WHERE   date_end >= @date_end 
        ) datetimerange
        -- Calculate the average price
        CROSS APPLY (
          SELECT  [AveragePrice] = SUM(price / DATEDIFF(dd, @date_start, @date_end))
          FROM    (
                    -- Price for all records where date_end <= @date_end 
                    SELECT  [price] = 
                              CASE WHEN @date_start < date_start 
                              THEN DATEDIFF(dd, date_start, date_end) * price
                              ELSE DATEDIFF(dd, @date_start, date_end) * price
                              END                        
                    FROM    @HouseSearch        
                    WHERE   @date_end > date_end
                    UNION ALL
                    -- Price of remaining records where date_end >= @date_end
                    SELECT  DATEDIFF(dd, date_start, @date_end) * price
                    FROM    @HouseSearch        
                    WHERE   @date_end between date_start AND date_end
                  ) prices
        ) price                  
WHERE   date_start IS NOT NULL            

Данные испытаний

DECLARE @HouseSearch TABLE (
  date_start DATE
  , date_end DATE
  , nb_people INTEGER
  , price FLOAT
)  

INSERT INTO @HouseSearch VALUES
  ('2011-01-01', '2011-01-25', 4, 100)
  , ('2011-01-25', '2011-02-14', 3, 120)
  , ('2011-02-14', '2011-03-12', 3, 140)
  , ('2011-03-12', '2011-04-10', 3, 100)

DECLARE @date_start DATE = '2011-01-15'
DECLARE @date_end DATE = '2011-03-01'
DECLARE @nb_people INTEGER = 3
DECLARE @price_low FLOAT = 90
DECLARE @price_high FLOAT = 15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...