2

これは私がいる複雑な状況です。部屋を予約する予約システムがあります。

重要なのは、部屋の料金は単一の値として保存されるのではなく、期間に基づいているということです。部屋のように、9月から12月の間に1日の料金を設定し、3月から8月に別の料金を設定することができますが、それ以外の場合は基本料金を設定できます。

料金表は次のようになります。

ROOMID | RATE | PERIOD_START | PERIOD_END

3月1日から3月31日までの部屋の料金が20ドル/日で、4月15日から5月30日までの同じ部屋の料金が30ドルであると仮定します。ただし、料金は15ドル/日の定額料金です。

この部屋が3月15日から5月10日の間に1人のクライアントによって予約された場合、合計費用は次のようになります。

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

コードでこの値を計算するにはどうすればよいですか。レート期間に基づいて日数を計算する必要があります。そうでない場合は、基本レートを使用します。その複雑ですが、それはそれがどのようであるかです。私はphpMySQLを使用しています

4

5 に答える 5

2

これは可能な解決アルゴリズムです:

  1. 予約期間と空でない交差があるすべてのレート期間を検索します
  2. (1)で見つかった料金期間ごとに、予約期間と交差する日数を計算し、期間の料金を掛けます
  3. 残りの日数(つまり、予約期間の日数から(2)で見つかったすべての日数の合計を差し引いたものが基本料金の日数です)

Re(1)、どのレート期間が予約期間と交差するかを見つけるために、2つの間隔が(A,B)あり(C,D)、交差が空であることに注意してくださいD < A or C > B。したがって、この条件を無効にすることができます。次のようになります。

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

max(booking_start, period_start)(2)に関しては、との間の日数を見つける必要がありますmin(booking_end, period_end)。日付を処理するユーティリティがあると確信していますが、最悪の場合はループするだけです。

申し訳ありませんが、私は実際のコードを書くためのSQL/phpウィザードではありません...:)

于 2011-02-23T21:47:13.310 に答える
1

PHPでは、 DateTimeを使用して2つの日付間の差の間隔を計算できます。

于 2011-02-28T14:55:38.537 に答える
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';

秘訣は、単一の日付フィールド d を持つ「days」というテーブルが必要だということです。そのテーブルに事前入力して、今から永遠に毎日を含めます。スクリプトを介して簡単に実行できます。将来の予約可能な日付をそこに保持するだけで済みます。

開始日と終了日の選択には注意が必要です。たとえば、3 月 31 日から 4 月 1 日までの間に部屋を予約した場合、それは正確にはどういう意味ですか?

それは20ドルの日と10ドルの日ですか?それとも1日20ドルだけ?それとも1日10ドル?

この回答自体には実際には影響しませんが、料金表の作成方法と、開始日と終了日として使用する日には影響します。

また、このバージョンでは、レート フィールドが完全な YYYY-MM-DD 形式を使用することを前提としています。これは絶対的な要件ではありませんが、MM-DD のみの場合は、結合を少し変更する必要があります。

個人的には、私はこのようにはしません。代わりに、DateIntervalクラスを使用して PHP コードで日数をループし、その方法で価格を照会します。

于 2011-02-23T22:22:17.413 に答える
1

考えられる解決策の 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。つまり、常に作業する日付が 2 つ以上ある可能性が高いということです。

予約表はこのようなものだと思います。

予約

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 に答える