【发布时间】:2015-03-11 14:20:21
【问题描述】:
我正在构建一个预订风格的系统。房间有一个年度标准价格(这是我的问题与其他类似问题不同的地方,因为其他房间有独特的范围)然后它们也有一年内的日期范围,价格不同。我正在寻找在 MYSQL 中计算价格,但是当用户选择在特殊日期范围内的日期时,它会将该价格相加,但也会将这些日期的标准价格相加,这意味着总数太高。这有点罗嗦所以这里是查询和一个例子:
SELECT SUM(Price * (1 + DATEDIFF(LEAST(End_date, '2015-07-25' - INTERVAL 1 DAY), GREATEST(Start_date, '2015-07-15')))) AS Total
FROM room_rates
WHERE roomId = '46' AND (
'2015-07-25' - INTERVAL 1 DAY BETWEEN Start_date AND End_date
OR '2015-07-15' BETWEEN Start_date AND End_date
)
+--------+------------+------------+------------+------+
| RoomId | Range Name | Start_Date | End_Date | Rate |
+--------+------------+------------+------------+------+
| 46 | Standard | 2015-01-01 | 2015-12-31 | 100 |
+--------+------------+------------+------------+------+
| 46 | Summer | 2015-07-20 | 2015-08-31 | 150 |
+--------+------------+------------+------------+------+
| 46 | Christmas | 2015-12-18 | 2015-12-31 | 180 |
+--------+------------+------------+------------+------+
如果用户在我的查询示例中选择 2015-07-15 到 2015-07-25,我想要这样计算:
- 2015-07-15 ... 2015-07-19 按标准价格(每晚 100 元)
- 2015-07-20 ... 2015-07-24 夏季价格(每晚 150)
总共应该是 1250。但是因为标准汇率的日期介于一年的第一天和最后一天之间,所以查询还包括该价格和夏季日期期间该范围内的总和汇率,这意味着我以标准价格收取所有 10 个日期的费用,加上以夏季价格收取的 5 晚费用,总计 1750。
所以我的问题是,如果没有其他选择,我该如何修改查询以仅使用标准费率?标准费率总是被称为“标准”,所以我可以很容易地识别它们,我只是不知道要做出什么改变!
编辑
我应该补充一下,我希望在 PHP 中执行此操作(我正在使用 PDO)
第二次编辑 另外值得注意的是,日期范围总是在一年内,并且日期范围不能重叠(除了占全年的标准费率)
解决方案
决定改变我的方法,并按照几个人建议的答案,建立一个日复一日的数据库。这是我最后的工作查询。感谢大家的帮助和建议。
SELECT standard_rates.villaId as `villaId`,
sum(IFNULL(custom_rates.nightly_rate_usd, standard_rates.nightly_rate_usd))
AS `Rate`
FROM dates
LEFT JOIN
villa_price_bands AS standard_rates
ON standard_rates.Name = 'Standard'
AND dates.date BETWEEN standard_rates.Start_Date AND standard_rates.End_Date
AND FIND_IN_SET(standard_rates.villaId, :resultIds)
LEFT JOIN
villa_price_bands AS custom_rates
ON custom_rates.Name != 'Standard'
AND dates.date BETWEEN custom_rates.Start_Date AND custom_rates.End_Date
AND custom_rates.villaId = standard_rates.villaId
WHERE dates.date >= :arrDate
AND dates.date < :deptDate
GROUP BY villaId
【问题讨论】:
-
我认为最好的方法是用光标(从 startDate 到 endDate)循环每一天,并将费率添加到每个日期的总和中。否则,您需要将其拆分为 N 个案例,其中 N 是未知的。
-
我希望在 PHP 中执行此操作,这可能吗?
-
这可能是更好的路线(更容易)。同样的概念也适用。您需要一个循环在日期范围内的每一天进行迭代。然后选择每个日期的价格并添加到总和中。
-
“在 PHP 中循环并为每一天执行一次查询” - 查询太多。最好通过一次查询从数据库中获取所有选项,并通过在 PHP 中进行比较来获取价格。始终尽可能少地执行数据库查询。
标签: php mysql sql datetime date-range