大家好,
我需要为房屋搜索创建一个查询,该查询将匹配数据库中用户输入的数据:他们想要入住和离开的日期、他们的团体人数和每晚价格。
假设用户搜索了房子:
日期:从 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/