2

这是一个复杂的情况。我有一个预订系统,可以预订房间。

问题是房间的价格不是作为一个单一的值存储的,而是基于周期的。就像一个房间在 9 月到 12 月之间可以有一个每日房价,从 3 月到 8 月可以有不同的房价,而在其他情况下可以有一个基本房价。

费率表是这样的:

ROOMID | RATE | PERIOD_START | PERIOD_END

假设 3 月 1 日至 3 月 31 日期间的房间价格为 20 美元/天,4 月 15 日至 5 月 30 日同一房间的价格为 30 美元,此外该价格是 15 美元/天的固定价格。

如果此房间由一位客户在 3 月 15 日至 5 月 10 日期间预订,则总费用为:

15th March - 31st march charged at 20 Dollars/day = 16x20
1st April - 14th April charged at 15 Dollars/day = 14x15
15th April - 10th May charged at 30 Dollars/day = 25x30

现在如何在代码中计算这个值,如果有的话,我需要根据费率周期计算天数,否则为它们使用基本费率。它很复杂,但就是这样。我正在使用 php MySQL

4

5 回答 5

2

这是一个可能的解决方案算法:

  1. 查找与预订期有非空交叉点的所有费率期
  2. 对于 (1) 中找到的每个费率期间,计算其与预订期间相交的天数,然后乘以期间的费率
  3. 剩余天数(即预订天数减去 (2) 中找到的所有天数的总和)是您的基本费率天数

关于(1),为了找出哪些费率期与预订期相交,请注意 2 个间隔(A,B)并且(C,D)有一个空交集 iff D < A or C > B,因此您可以否定这个条件。应该看起来像:

SELECT * FROM rates 
   WHERE NOT (booking_end < period_start OR 
              booking_start > period_end)

Re (2),你只需要找到 和 之间的天数max(booking_start, period_start)min(booking_end, period_end)包括在内。我确信有一些实用程序可以处理日期,但在最坏的情况下,您可以循环浏览它。

抱歉,但我不是编写实际代码的 SQL/php 向导... :)

于 2011-02-23T21:47:13.310 回答
1

一种可能的解决方案是使用一个名为 price_periods 的表,其中包含开始日期、结束日期和价格以及对房间的引用。

所以 SQL 表看起来像这样。

PRICE_PERIODS

PPID | ROOM_ID | PP_START_DATE | PP_END_DATE | PP_PRICE
-------------------------------------------------------
1      2         09-20           10-20         15
2      2         10-21           11-20         20

然后您只需计算预订的日期,因此假设 A 想从 10-11 到 10-25 租一个房间,他必须支付 ID 为 1 的 PRICE_PERIOD,直到 PP_END_DATE 发生然后支付id 为 2 的 PRICE_PERIOD,直到预订结束。所以问题是你可能随时都有两个以上的约会。

我想您的预订表看起来像这样。

预订

B_ID | ROOM_ID | USER_ID | START_DATE | END_DATE
------------------------------------------------
1      2         4         10-11        10-25

您必须进行计算,但有一个可能会起作用的开始。

于 2011-02-23T18:07:01.467 回答
1

试试这个。

这会在预订期间的每一天循环,从表中找到适当的费率,然后将其添加到总数中。

$Day="2011-03-15";
$End="2011-05-10";
$Periods=array(); // Filled with the Mysql rows - mysql_fetch_assoc()
$Total=0;

编辑

更优化。

foreach($Periods as $Period) {
    if($Day>=$Period['PERIOD_START']&&$Day<=$Period['PERIOD_END']) {
        while($Day<=$End&&$Day<=$Period['PERIOD_END']) {
            $Total+=$Period['RATE'];
            $Day=date('Y-m-d',strtotime("$Day +1 day"));
        }
    }
}
于 2011-02-23T18:07:45.403 回答
1

这里只是一个半认真的答案。

如果你想要一个 SQL 查询,你可以这样做:

SELECT SUM(IF(ISNULL(r.rate), 10, r.rate))
FROM days AS d
LEFT JOIN rates AS r ON d.d BETWEEN r.start AND r.end
  WHERE d.d BETWEEN '2011-03-15' and '2011-05-10';

诀窍是您需要一个名为“days”的表,它有一个日期字段 d。预先填充该表以包括从现在到永恒的每一天。通过脚本很容易做到;您只需要在其中保留未来的可预订日期。

请注意,您必须小心选择开始日期和结束日期。例如,如果您在 3 月 31 日至 4 月 1 日之间预订房间,这究竟意味着什么?

那是一天 20 美元和一天 10 美元吗?还是只有一天 20 美元?还是单日 10 美元?

它本身并不会真正影响这个答案,但它确实会影响您如何构建费率表以及您使用哪一天作为开始和停止。

此外,此版本假设费率字段使用完整的 YYYY-MM-DD 格式。这不是绝对要求,但如果它只是 MM-DD,那么您必须稍微修改联接。

就个人而言,我不会这样做。相反,我只是在 PHP 代码中使用DateInterval类循环并以这种方式查询价格。

于 2011-02-23T22:22:17.413 回答
1

在 PHP 中,您可以使用DateTime计算两个日期之间的差异间隔。

于 2011-02-28T14:55:38.537 回答