我有一个预订系统,我需要从数据库中选择任何可用的房间。基本设置是:MySQL选择日期不在日期之间的行
table: room
columns: id, maxGuests
table: roombooking
columns: id, startDate, endDate
table: roombooking_room:
columns: id, room_id, roombooking_id
,我需要选择的客房,可容纳请求的客人,或选择两个(或更多)的房间,以适应宾客(由maxGuests定义,显然用最低/壁橱maxGuests第一)
我可以遍历我的日期范围,并使用此SQL:
SELECT `id`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`, `roombooking`
WHERE `roombooking`.`confirmed` =1
AND DATE(%s) BETWEEN `roombooking`.`startDate` AND `roombooking`.`endDate`
)
AND `room`.`maxGuests`>=%d
其中,%$ 1是环状日期%2d是在被预订的客人数量,但这将只是如果有多于任何房间的客人可以返回假,并且必须有一个quic更好的方式做到这一点,而不是循环与PHP和运行查询?
这类似于SQL的一部分,我想的是:Getting Dates between a range of dates但与MySQL
解决方案的基础上,ircmaxwell的回答是:
$query = sprintf(
"SELECT `id`, `maxGuests`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`
JOIN `roombooking` ON `roombooking_room`.`roombooking_id` = `roombooking`.`id`
WHERE `roombooking`.`confirmed` =1
AND (`roomBooking`.`startDate` > DATE(%s) OR `roomBooking`.`endDate` < DATE(%s))
)
AND `maxGuests` <= %d ORDER BY `maxGuests` DESC",
$endDate->toString('yyyy-MM-dd'), $startDate->toString('yyyy-MM-dd'), $noGuests);
$result = $db->query($query);
$result = $result->fetchAll();
$rooms = array();
$guests = 0;
foreach($result as $res) {
if($guests >= $noGuests) break;
$guests += (int)$res['maxGuests'];
$rooms[] = $res['id'];
}
为什么你有一个单独的roombooking_room表?不应该tablerooming:id,room_id,startDate,endDate是否够了? – Axarydax 2010-11-12 14:44:21
我认为,为了实现目标,对于想要实现的目标而言,执行所需任务所需的SQL会过于复杂。循环和使用PHP有什么问题?您也可能会发现,如果您使用纯SQL实现期望的结果,则该解决方案实际上可能比用PHP循环更慢。但是,我对看到结果非常感兴趣,因为我有时会发现自己提出了一个类似的问题(PHP vs SQL)。 – 2010-11-12 15:01:22
@Axaryday请在下面看到关于答案的评论。这是必要的,因为一个预订周期可能有多个房间关联。即,我住10人,一个房间可以带6人,因此我需要两个房间,但在相同的预订 – Ashley 2010-11-12 15:50:58