Цены на гостиничные номера для разных сезонов - PullRequest
2 голосов
/ 10 января 2011

У меня есть база данных (MySQL) с таблицей, содержащей диапазоны дат (как startdate и enddate) и поле оценки. Диапазон дат подразумевает разные времена года (низкий, высокий и т. Д.). Сценарий таков, что человек регистрируется в отеле, и его продолжительность пребывания составляет два сезона. Пример данных как ниже:

SeasonName         SartDate            EndDate           Rate
Low                01-01-2007          30-04-2007        100.00
High               01-05-2007          31-08-2007        150.00
Peak               01-09-2007          31-12-2007        200.00

Дата регистрации клиента - 29-04-2007, а Дата выезда - 03-05-2007. Мне нужно рассчитать точное количество ночей для каждого сезона, а также рассчитать общую сумму.

IDE - это VB6. Любая помощь будет чрезвычайно ценится.

Спасибо

Tom

Спасибо за ответ. Мне нужен SQL для извлечения информации. Что касается срока действия даты, давайте предположим, что ставка применяется до полуночи (00:00). Надеюсь, я уточнил.

Tom

Ответы [ 4 ]

8 голосов
/ 10 января 2011

Поработав в отеле и написав систему бронирования, почасовое время не имеет значения для выставления счетов.Все всегда заряжено ночью.(Если вы не планируете управлять местом, которое заряжается каждый час! ;-)) Регистрация заезда и отъезда являются эксплуатационными соображениями.

Не используйте сохраненные процедуры, если вы действительно хотите написать реальную систему бронирования.Это побеждает цель иметь базу данных.

Кроме того, написание таких дат - 2007-04-29 - действительно отличный способ, потому что не все из одного места, и это международный стандарт.Также обратите внимание, что если вы превратите это в строку, она все равно будет отсортирована правильно!

Вам нужно создать таблицу calandar, так как MySQL не имеет встроенных функций для этого.Эта процедура создаст для вас даты.

drop table if exists calendar;
create table calendar 
( 
    date_       date        primary key
);

drop procedure fill_calendar;

delimiter $$
create procedure fill_calendar(start_date date, end_date date)
begin
  declare date_ date;
  set date_=start_date;
  while date_ < end_date do
    insert into calendar values(date_);
    set date_ = adddate(date_, interval 1 day);
  end while;
end $$
delimiter ;

call fill_calendar('2007-1-1', '2007-12-31');

с: http://www.ehow.com/how_7571744_mysql-calendar-tutorial.html

drop table if exists rates;
create table rates
(
    season          varchar(100)    primary key,
    start_date      date            references calendar(date_),
    end_date        date            references calendar(date_),
    rate            float
);
insert into rates values ('Low',    '2007-01-01',   '2007-04-30',   100.00);
insert into rates values ('High',   '2007-05-01',   '2007-08-31',   150.00);
insert into rates values ('Peak',   '2007-09-01',   '2007-12-21',   200.00);

select * from rates;
season  start_date      end_date        rate
Low     2007-01-01      2007-04-30      100
High    2007-05-01      2007-08-31      150
Peak    2007-09-01      2007-12-21      200

Я собираюсь игнорировать даты, которые вы задали в своем вопросе, и предположить, чтоклиент не движется назад во времени.

select
    date_, rate
    from calendar
    join rates
        on date_ >= start_date and date_ <= end_date

    where date_ between '2007-04-29' and '2007-5-01'
;
date_   rate
2007-04-29      100
2007-04-30      100
2007-05-01      150

select
    sum(rate)

    from calendar
    join rates
        on date_ >= start_date and date_ <= end_date

    where date_ between '2007-04-29' and '2007-5-01'
sum(rate)
350

И, как вы можете видеть, SQL очень лаконичен и удобен для чтения, не прибегая к функциям или процедурам.Это позволит правильно масштабировать и решать более сложные вопросы.Кроме того, он позволяет использовать ссылочную проверку, поскольку данные основаны на таблицах.

1 голос
/ 10 января 2011

Я использовал функцию DATEDIFF , чтобы узнать количество дней между двумя датами. Но так как эта функция возвращает количество дней, исключая последний день (например, DATEDIFF(d, '2007-04-29', '2007-04-30') возвращает 1 вместо 2), я использовал такую ​​таблицу тарифов:

SeasonName         StartDate           EndDate           Rate
Low                01-01-2007          01-05-2007        100.00
High               01-05-2007          01-09-2007        150.00
Peak               01-09-2007          01-01-2008        200.00

Это запрос, который я использовал. Внутренняя часть двух SELECT вычисляет эффективную дату окончания пребывания клиента в зависимости от сезона (либо дата окончания сезона, либо его дата до даты его отъезда).

Я использовал 02-05-2007 в качестве даты окончания пребывания клиента вместо 03-05-2007, так как обычно клиент не платит за день, когда он выписывается.

SELECT SeasonName, DATEDIFF(d, '2007-04-29', EffectiveEndDate) as NumberOfDays, Rate
FROM (
    SELECT SeasonName, 
    CASE 
    WHEN EndDate < '2007-05-02' THEN EndDate
    ELSE '2007-05-02' 
    END AS EffectiveEndDate, 
    Rate
    FROM HotelRate
    WHERE (StartDate <= '2007-04-29' and EndDate > '2007-04-29')
    or (StartDate <= '2007-05-02' and EndDate > '2007-05-02')
) as SubSelect

Это дает мне такой результат:

SeasonName NumberOfDays  Rate
Low        2             100.00
High       3             150.00

Надеюсь, это поможет:)

0 голосов
/ 10 января 2011

Используйте вспомогательную календарную таблицу :

SELECT S1.client_ID, H1.Rate, C1.dt
  FROM HotelRates AS H1
       INNER JOIN Calendar AS C1
          ON C1.dt BETWEEN H1.SartDate AND H1.EndDate
       INNER JOIN Stays AS S1
          ON C1.dt >= check_in_date AND 
             C1.dt < check_out_date;
0 голосов
/ 10 января 2011

Отказ от ответственности : Это не самый эффективный, но более понятный вариант, и если в массиве будет кэширован прайс-лист, снижение производительности будет бессмысленным.

Dim numberOfDays As Integer, i As Integer
Dim CheckInDate As Date, CheckOutDate As Date, CurrDate As Date
Dim TotalRate As Currency
TotalRate = 0
CheckInDate = DateSerial(2007, 4, 29)
CheckOutDate = DateSerial(2007, 5, 3)
''// -1 asumming the last day is checkout day
numberOfDays = DateDiff("d", CheckInDate, CheckOutDate) - 1 
For i = 0 To numberOfDays
   CurrDate = DateAdd("d", i, CheckInDate)
   TotalRate = TotalRate + CalculateRateForDay(CurrDate)
Next
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...