【问题标题】:Hotel Room Rates for different seasons不同季节的酒店房价
【发布时间】:2011-06-06 13:20:59
【问题描述】:

我有一个数据库 (MySQL),其中包含一个包含日期范围(如 startdate 和 enddate)和一个 rate 字段的表。日期范围意味着不同的季节(低、高等)。场景是这样的,一个人入住酒店,他的逗留时间是两个季节。示例数据如下:

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。任何帮助将不胜感激。

谢谢

汤姆

感谢您的回复。我需要 SQL 来提取信息。至于日期有效性,假设费率适用于午夜 (00:00)。希望我已经澄清了。

汤姆

【问题讨论】:

  • 您遇到了什么问题? SQL?用来运行它的代码?解析数据?渲染数据?需要更多信息。
  • 一夜横跨两天;您首先需要定义 4 月 30 日结束的费率是否适用于一天结束时的晚上,或者同一晚是否使用 5 月 1 日的费率

标签: mysql date vb6 range


【解决方案1】:

免责声明:这不是最有效的,但它更清楚,如果您将价目表缓存在数组中,性能损失将毫无意义。

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

【讨论】:

    【解决方案2】:

    我使用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
    

    希望对你有帮助:)

    【讨论】:

    • 我猜你的解决方案太受限制了。如果猜测停留超过 2 个季节会发生什么? (大多数酒店在长周末、节假日等都有特价)
    • 你说得对,这不适用于长期住宿。我喜欢 nate c 的带有详细日历表的解决方案。
    【解决方案3】:

    使用auxiliary calendar table

    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;
    

    【讨论】:

      【解决方案4】:

      在酒店工作并编写了预订系统,每小时时间是无关紧要的 随着计费的进行。一切总是在晚上收费。 (除非您打算经营一个按小时收费的地方!;-)) 入住和退房是运营方面的考虑因素。

      如果您真的想编写一个真正的预订系统,请不要使用存储过程。 它违背了拥有数据库的目的。

      另外,写出这样的日期是 2007-04-29 真的很棒,因为不是每个人都来自同一个地方,这是一个国际标准。还要注意,如果你把它变成一个字符串,它仍然会被正确排序!

      您需要创建一个日历表,因为 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 非常简洁易读,无需借助函数或过程。这将能够正确扩展并处理更复杂的问题。此外,由于数据是基于表的,因此可以使用引用检查。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        • 2017-08-27
        • 1970-01-01
        • 2022-11-11
        • 2016-03-29
        • 2013-09-06
        相关资源
        最近更新 更多