Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 计算租期价格_Php_Mysql_Sql - Fatal编程技术网

Php 计算租期价格

Php 计算租期价格,php,mysql,sql,Php,Mysql,Sql,我正在做一个项目,我需要计算在选定的租赁期内度假屋的价格。我需要一些帮助来构建一个SQL查询,该查询组合了下表,并将数据转换为一个输出,该输出包含每个房子所需期间的价格。它应该包含住宿费用、附加费用类型以及承租人应为每种费用类型支付的金额 我有一个表costprofiles,使房主能够在一年中拥有多种价格: +----------------+----------+--------------+ | costprofile_id | house_id | profile_name | +----

我正在做一个项目,我需要计算在选定的租赁期内度假屋的价格。我需要一些帮助来构建一个SQL查询,该查询组合了下表,并将数据转换为一个输出,该输出包含每个房子所需期间的价格。它应该包含住宿费用、附加费用类型以及承租人应为每种费用类型支付的金额

我有一个表costprofiles,使房主能够在一年中拥有多种价格:

+----------------+----------+--------------+
| costprofile_id | house_id | profile_name |
+----------------+----------+--------------+
|              1 |      312 | summer       |
+----------------+----------+--------------+
|              2 |      312 | winter       |
+----------------+----------+--------------+
我有一个名为costprofile\u items的表,该表通过外键costprofile\u id链接到costprofile。该表包含如果选定期间的价格使用此cost\u类型,承租人应向所有者支付的所有不同金额。每个额外金额可通过四种不同方式计算:

  • 每晚
  • 每次住宿
  • 每人
  • 每人每晚
  • 每个金额对总租金的贡献方式存储在“计算类型”列中。这是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 |
    +---------------------+----------------+--------+-------------+----------------------+
    
    +----------+----------+----------------+------------+------------+-----------+--------+
    | 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 |
    +----------+----------+----------------+------------+------------+-----------+--------+
    
    我还有一个价格表,其中每行代表每晚的价格,可以在开始日期和结束日期之间使用(开始日期的工作日等于到达房屋的工作日,结束日期的工作日等于出发的工作日)。该行还包含一列nights,用于确定子时段需要多长时间才能使用此价格。这是该表的外观:

    +---------------------+----------------+--------+-------------+----------------------+
    | 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 |
    +---------------------+----------------+--------+-------------+----------------------+
    
    +----------+----------+----------------+------------+------------+-----------+--------+
    | 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欧元。请注意,每个入住和每个人的计算类型只需要从第一个子周期中选择,因此最后一个示例中的清洁只支付一次

    我用于计算价格的最后一个表是“每个组的价格”。此表通过外键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循环遍历包含某栋房子价格信息的所有行。我从开始日期开始,使用它可以找到的第一个可用价格行进行步骤,并重复该步骤,直到结束日期。我目前的方法的问题是速度太慢。对于1000个房屋,Web服务器需要0.3秒的执行时间。也许可以在我的PHP代码中进行一些优化,但我希望有人能帮助我将这些都放在SQL中。例如,这种方式更容易实现按价格排序,在快速执行上述查询后,只需请求较大的结果,即可使我的执行时间增加到0.12秒


    欢迎所有的帮助和建议

    最后,我决定缓存所有价格,而不是实时计算它们。这将产生更好的性能,并允许比在查询中实时计算更复杂的定价。每晚运行一个cronjob,填满21个表(每个可能的租用期限对应一个表)。持续时间定价表包含到达日期的键、值对以及该持续时间的相应计算价格。或者,您可以添加组大小列,从而得出每个持续时间、每个组大小、每个到达日期的价格。它需要相当多的数据库记录,但若您创建索引,这会非常快。

    我想您想要创建一个行的索引吗?不幸的是,它比那个更复杂。在生成的集合中,我得到的行只有开始日期和结束日期,在这些日期房价是有效的。例如,我可能需要一个包含3次周价格的行,而我不使用包含周末价格的行。