php - 查询 : Calculate average price of stay depending on dates

标签 php sql search stored-procedures

periods

大家好,

我需要为房屋搜索创建一个查询,该查询将匹配数据库中用户输入的数据:他们想要入住和离开的日期、他们的团体人数和每晚价格。

假设用户搜索了房子:

日期:从 2011-01-15 到 2011-03-01(见图片期间 A1C1),3 人,他愿意每晚花费 $90 到 $125 美元。

这是我对该搜索的手动计算:

  • 数据库中可用的日期
  • 用户希望停留的总天数是:44 天
  • 2011-01-15 到 2011-01-25 第一期的价格是 10 天 * 100 美元 = 1000 美元
  • 2011-01-25 到 2011-02-14 第二个周期的价格是 20 天 * 120 美元 = 2400 美元
  • 第三个周期 2011-02-14 到 2011-03-01 的价格是 14 天 * 140 美元 = 1960 美元
  • 每晚总平均价格 = 1000 + 2400 + 1960/44 = 121.8 美元
  • 价格和人数与用户输入相匹配,所以我们展示这个房子

如果您合并日期并计算给定期间每晚的平均价格,搜索脚本应与上面提供的数据数组匹配。

我的问题是:如果用户数据与数据库中的记录匹配,我的查询应该如何快速计算

我正在考虑使用 SQL DATEDIFF 函数,然后乘以价格......等等,但在我看来它非常复杂。

我将不胜感激任何建议。

谢谢

更新

这是我的数据库模式:

存储所有合并日期的表“apt_search_periods”(可用性表中的连续日期)

+-----------+------------+------------+-----------+--------------+--------+
| period_id | start_date | end_date   | rental_id | nb_of_people | merged |
+-----------+------------+------------+-----------+--------------+--------+
|        21 | 2011-03-31 | 2012-03-31 |       548 |            4 | y      |
+-----------+------------+------------+-----------+--------------+--------+

表“apt_search_periods_avail”将合并日期与可用性表链接

+----+-----------+-----------------+
| id | period_id | availability_id |
+----+-----------+-----------------+
| 21 |        21 |           20953 |
| 22 |        21 |           20952 |
| 23 |        21 |            4033 |
+----+-----------+-----------------+

带有扩展日期和价格的“可用性”表

+-------+-----------+------------+------------+--------------+--------------+
| id    | rental_id | start_date | end_date   | nb_of_people | rent_per_day |
+-------+-----------+------------+------------+--------------+--------------+
| 20952 |       548 | 2011-03-31 | 2011-07-01 |            4 |          575 |
|  4033 |       548 | 2011-07-01 | 2011-09-01 |            4 |          680 |
| 20953 |       548 | 2011-09-01 | 2012-03-31 |            4 |          575 |
+-------+-----------+------------+------------+--------------+--------------+

最佳答案

以下应该可以帮助您入门。

请注意,唯一的区别是根据 DATEDIFF,第三个时间段包括 15 天或 14 天。

SQL语句

;WITH q AS (
  /* Kick of with the record where startdate < input < enddate */
  SELECT  date_start
          , date_end
  FROM    @HouseSearch
  WHERE   date_start <= @date_start
          AND date_end >= @date_start
          AND nb_people >= @nb_people -- Only when number of people is adequate
  UNION ALL
  SELECT  q.date_start
          , hs.date_end
  FROM    q
          INNER JOIN @HouseSearch hs ON hs.date_start = q.date_end
  WHERE   nb_people >= @nb_people -- Only when number of people is adequate
)
SELECT  *
FROM    (
          -- Only return result if sequence exists between date range
          SELECT  date_start = MIN(date_start)
                  , date_end = MAX(date_end)
          FROM    q
          WHERE   date_end >= @date_end 
        ) datetimerange
        -- Calculate the average price
        CROSS APPLY (
          SELECT  [AveragePrice] = SUM(price / DATEDIFF(dd, @date_start, @date_end))
          FROM    (
                    -- Price for all records where date_end <= @date_end 
                    SELECT  [price] = 
                              CASE WHEN @date_start < date_start 
                              THEN DATEDIFF(dd, date_start, date_end) * price
                              ELSE DATEDIFF(dd, @date_start, date_end) * price
                              END                        
                    FROM    @HouseSearch        
                    WHERE   @date_end > date_end
                    UNION ALL
                    -- Price of remaining records where date_end >= @date_end
                    SELECT  DATEDIFF(dd, date_start, @date_end) * price
                    FROM    @HouseSearch        
                    WHERE   @date_end between date_start AND date_end
                  ) prices
        ) price                  
WHERE   date_start IS NOT NULL            

测试数据

DECLARE @HouseSearch TABLE (
  date_start DATE
  , date_end DATE
  , nb_people INTEGER
  , price FLOAT
)  

INSERT INTO @HouseSearch VALUES
  ('2011-01-01', '2011-01-25', 4, 100)
  , ('2011-01-25', '2011-02-14', 3, 120)
  , ('2011-02-14', '2011-03-12', 3, 140)
  , ('2011-03-12', '2011-04-10', 3, 100)

DECLARE @date_start DATE = '2011-01-15'
DECLARE @date_end DATE = '2011-03-01'
DECLARE @nb_people INTEGER = 3
DECLARE @price_low FLOAT = 90
DECLARE @price_high FLOAT = 15

关于php - 查询 : Calculate average price of stay depending on dates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5997160/

相关文章:

search - 在 vi/vim 中,是否可以创建一个映射来将单词连接到动态搜索?

php - Laravel 在服务器上传后无法访问存储在存储文件夹中的图像

PHP:文件写入权限

c# - 从多个基础的表中选择信息

sql - 基于 SQL 查询将值添加到下拉列表

database - 键值对的算法,其中键是字符串

php - 如何在数据库查询结果中显示多个html表中的数据

php - 有没有更好的方法来插入记录?

php - 用一个 SQL 查询拯救 20 个用户?

language-agnostic - 类似于 Google 代码搜索的源代码索引器和可视化器