尊敬的Stackoverflow成员,
我的问题
我在MYSQL中需要以下帮助: 对于出租住宿的网站,我需要计算房间的可用性。
一种情况: 用户想在2018年10月21日预订7人的住宿,共8人。 然后,系统需要查找所有在住宿期间每天可容纳8人的房间的住宿。这可以是房间的任意组合。
我的表结构(仅必要的列):
项目(带住宿的桌子): ID
可用性: id | fkItemRoom | arrival_date | arrival_possible | departure_possible |分配
item_room: id | fkItemId | fkRoomId
房间: id | max_occupancy
可用性表中的每一行都是带有物料室的日期,该日期指示该日期是否有分配。因此,要计算7个晚上的可用性,一个房间需要在可用性表中有7行,连续7天为该物料室分配该空间。
我当前的解决方案:
此解决方案返回所有可用的容纳空间,并且使用SUM,我采取了一些方法来计算可用性。我知道这不是正确的方法。
$vars['allotment'] = 8;
$vars['duration'] = $duration;
$ids = array();
$availableParts = array();
$allotmentParts = array();
$wParts = array();
foreach($arrivalDates as $key => $date) {
$durationDates = array();
for($i = 0; $i < $duration; $i++) {
$durationDates[] = strtotime(date('11:00 d-m-Y',strtotime("+ $i days",$date['from'])));
}
$arrivalDate = $date['from'];
$departureDate = $date['till'];
$availableParts[] = "(SELECT count(id) FROM availability ea WHERE ea.arrival_date IN(".implode(',',$durationDates).") AND ea.allotment > :allotment AND ea.fkItemRoom = ir.id)";
$allotmentParts[] = "(SELECT SUM(ea.allotment * r.max_occupancy) FROM availability ea WHERE ea.arrival_date IN(".implode(',',$durationDates).") AND ea.allotment > 0 AND ea.fkItemRoom = ir.id)";
$wParts[] = "(ir.id IN (SELECT fkItemRoom FROM availability ea WHERE ea.arrival_date = $arrivalDate AND ea.arrival_possible = 1 AND ((ea.is_maximum IS NULL AND ea.minimum_stay <= :duration) OR (ea.is_maximum = 1 AND ea.minimum_stay = :duration)))
AND
ir.id IN (SELECT fkItemRoom FROM availability ea WHERE ea.arrival_date = $departureDate AND ea.departure_possible = 1))";
}
$query = "
SELECT
ir.fkItemId,
GREATEST(".implode(',', $availableParts).",-1) as total_available,
GREATEST(".implode(',', $allotmentParts).",-1) as total_allotment
FROM
item_room ir
INNER JOIN
room r
ON
r.id = ir.fkRoomId
WHERE
(".implode(' OR ', $wParts).")
GROUP BY
ir.fkItemId
HAVING
total_available >= :duration AND total_allotment >= :allotment";
我需要此解决方案来考虑可伸缩性和性能。 如果需要更多信息,请询问,我会提供。
该脚本是用PHP 7.2和MYSQL编写的。
如果您不懂PHP:
php代码在每个时段(从开始日期到结束日期)都会生成多个查询。用户可以选择在+-2天内获得结果。然后,主查询接受所有这些子查询,并将它们与php函数“ implode”一起放入mysql“ GREATEST”函数。此时,查询仅需要知道是否存在一个具有足够可用天数和分配量的期间。
免责声明
我不是在寻找可以给我完美算法的人。我想学习和理解如何处理这种情况。创建一个视图,将其拆分为多个查询,重新考虑我的整个数据库结构。这只是许多其他复杂情况中的一种现实情况。