[英]Calculate price of rental period
我正在從事一個項目,我需要計算選定租賃期內可用度假屋的價格。 我需要一些幫助來構建一個 SQL 查詢,該查詢結合了以下表格,並將數據轉換為包含每所房子所請求時期的價格的輸出。 它應該包含住宿費用、額外費用類型以及承租人應為每個cost_type支付的金額。
我有一個表costprofiles ,它使房主全年可以有多個價格:
+----------------+----------+--------------+
| costprofile_id | house_id | profile_name |
+----------------+----------+--------------+
| 1 | 312 | summer |
+----------------+----------+--------------+
| 2 | 312 | winter |
+----------------+----------+--------------+
我有一個名為costprofile_items的表,它通過外鍵costprofile_id鏈接到一個成本配置文件。 如果所選期間的價格使用此cost_type ,則此表包含租戶應向所有者支付的所有不同金額。 每個額外的金額可以通過四種不同的方式計算:
每個金額對總租金價格的貢獻方式存儲在calculation_type列中。 這是costprofile_items表的樣子:
+---------------------+----------------+--------+-------------+----------------------+
| costprofile_item_id | costprofile_id | amount | cost_type | calculation_type |
+---------------------+----------------+--------+-------------+----------------------+
| 1 | 1 | 20 | usage_cost | per_night |
+---------------------+----------------+--------+-------------+----------------------+
| 2 | 1 | 8.5 | cleaning | per_stay |
+---------------------+----------------+--------+-------------+----------------------+
| 3 | 1 | 0.82 | tourist_tax | per_person_per_night |
+---------------------+----------------+--------+-------------+----------------------+
我還有表價格,其中每一行代表每晚的價格,可以在start_date和end_date之間使用( start_date的工作日等於到達房子的工作日, end_date的工作日等於出發的工作日) . 該行還包含一列nights ,用於確定子期間需要多長時間才能使用此價格。 這是表的樣子:
+----------+----------+----------------+------------+------------+-----------+--------+
| price_id | house_id | costprofile_id | start_date | end_date | per_night | nights |
+----------+----------+----------------+------------+------------+-----------+--------+
| 1 | 1 | 1 | 2014-08-04 | 2014-12-01 | 60 | 7 |
+----------+----------+----------------+------------+------------+-----------+--------+
| 2 | 1 | 1 | 2014-08-08 | 2014-12-05 | 70 | 3 |
+----------+----------+----------------+------------+------------+-----------+--------+
| 3 | 1 | 2 | 2014-12-01 | 2015-03-02 | 0 | 1 |
+----------+----------+----------------+------------+------------+-----------+--------+
在表格中,您可以看到,對於給定的房屋,您可以預訂 8 月 8 日至 11 日的期間,住宿費用為 3*70 = 210 歐元。 如果您與 4 人同行,額外費用為 3*20 = 60 歐元的電力/天然氣使用費、8.5 歐元的清潔費和 0.82*4*3 = 9.84 歐元的旅游稅。 因此,您周末的總費用為 288.34 歐元。 也應該可以將這個周末與例如表第一行中描述的每周價格的 2 倍結合起來。 在這種情況下,8 月 8 日至 25 日的價格將為 288.34 + 2*582.96 = €1454.26。 注意計算類型per_stay和per_person只需要從第一個子周期中選擇,所以最后一個例子中的清潔只支付一次。
我用來計算價格的最后一個表是price_per_group表。 該表通過外鍵price_id連接到價格。 在上面的價格表中,您可以在最后一行看到每晚的價格等於 0。在這種情況下,業主為他在此期間在其房屋中接受的每個人數給出了每晚的價格,此價格是有效的。 這是這些不同價格的存儲方式:
+--------------------+----------+------------+-----------+
| price_per_group_id | price_id | group_size | per_night |
+--------------------+----------+------------+-----------+
| 1 | 3 | 5 | 50 |
+--------------------+----------+------------+-----------+
| 2 | 3 | 4 | 45 |
+--------------------+----------+------------+-----------+
如您所見,從 12 月 1 日(或之后的任何星期一,但在 3 月 2 日之前)開始的一周,如果您有 5 人,則每晚將花費 50 歐元,如果您有 4 人,則每晚將花費 45 歐元。
我希望現在很清楚我如何嘗試存儲和計算所有不同的價格。
通過首先使用以下查詢查詢每個可用房屋的所有成本類型,我設法使這些計算正常工作:
SELECT * FROM (
SELECT prices.house_id,
prices.price_id,
prices.costprofile_id,
prices.nights,
prices.start_date,
prices.end_date,
MIN(
prices.per_night + COALESCE(prices_per_group.per_night, 0)
) AS per_night /* Add the price per night from prices and prices_per_group (if one has a non-zero value the other is always zero) */
FROM prices
LEFT JOIN prices_per_group ON prices.price_id = prices_per_group.price_id
WHERE prices.house_id IN (
/* Query that returns a set with the ids of all available houses here */
)
AND (
prices_per_group.price_id IS NULL OR /* If true, no row in prices_per_group is pointing to the price_id currently being evaluated */
prices_per_group.group_size >= 4 /* If true, the group_size satisfies the requested number of persons */
)
GROUP BY prices.price_id
) AS possible_prices
INNER JOIN costprofile_items ON costprofile_items.costprofile_id = possible_prices.costprofile_id
ORDER BY price_id ASC
之后,我使用 PHP 遍歷包含某個房子的價格信息的所有行。 我從start_date開始,並使用它可以找到的第一個可用價格行進行步驟,並重復該行,直到我到達end_date為止。 我目前的方法的問題是它太慢了。 對於 1000 所房屋,網絡服務器需要 0.3 秒的執行時間。 也許可以在我的 PHP 代碼中進行一些優化,但我希望有人可以幫助我將所有這些放在 SQL 中。 這種方式例如按價格排序更容易實現,並且在快速執行上述查詢后僅要求大結果使我的執行時間跳到 0.12 秒。
歡迎所有幫助和建議
最后我決定緩存所有價格而不是實時計算它們。 這會帶來更好的性能,並允許比在查詢中動態計算更復雜的定價。 每天晚上都會運行一個 cronjob,填滿 21 個表(每個可能的租用時間的表)。 持續時間定價表包含到達日期的鍵值對以及該持續時間的相應計算價格。 或者,您可以為團隊規模添加一列,從而得出每個持續時間、每個團隊規模、每個到達日期的價格。 它需要相當多的數據庫記錄,但是如果您創建索引,這將非常快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.