我想使用 PHP 创建一个预订酒店的房间,并查看任何可用的房间,我使用这样的查询:
SELECT * FROM m_room WHERE room_id NOT IN
(SELECT order_room FROM m_order WHERE
'$start' >= order_bookstart AND '$end' < order_bookend)
ORDER BY room_name
$start
和 $end
是从文本框输入的。用户先填写开始输入和结束输入,点击搜索后,会显示可用的房间。根据我的查询,如果我的示例数据存在于 m_order 中:room_id->1;开始-> 2015-05-13;结束-> 2015-05-16
然后当我将 $start
填入:2015-05-14 并将 $end
填入:2015-05-15 ,正常工作,room_id 没有。 1 不会出现,但如果我将日期 $start
填入:2015-05-14 并将 $end
填入:2015-05-19, room_id 号1 仍然出现,这一定不是因为从 2015-05-13 到 2015-05-16 仍然被客户使用
那么,如何修复我的查询以显示任何可用房间?
最佳答案
我认为您可能采用了错误的方法。您想要查找整个期间都可用的房间,这意味着如果有任何预订的开始日期或结束日期包含您要查找的期间的开始日期或结束日期,则它必须是拒绝了。
我们可以使用 where not exists
来完成这个。例如,查询 14 号到 15 号是否有空房:
select *
from m_room
where not exists (
select 1
from order_room
where room_id = m_room.room_id
and ('2015-05-14' between start_date and end_date
or '2015-05-15' between start_date and end_date
or start_date between '2015-05-14' and '2015-05-15')
);
作为第二个选项,您还可以左联接
order_room
表,将日期范围放入联接条件中,然后检查所在的行>order_room
值为 null
。
select *
from m_room
left join order_room
on m_room.room_id = order_room.room_id
and ('2015-05-14' between start_date and end_date
or '2015-05-15' between start_date and end_date
or start_date between '2015-05-14' and '2015-05-15')
where start_date is null;
this demo也有 left join
选项,显示结果是等价的。这种方法的优点是您可以获得两个有意义的结果 - 它向您显示绝对可用的房间,如果您删除 where
子句,它还会向您显示与另一个冲突的预订时间房间。
如果您希望允许在与其他预订的退房/入住日期重叠的同一天入住/退房,我们只需将日期范围修改一天,如下所示:
select *
from m_room
where not exists (
select 1
from order_room
where room_id = m_room.room_id
and ('2015-05-16' between start_date and end_date - interval 1 day
or '2015-05-20' between start_date - interval 1 day and end_date
or start_date between '2015-05-16' and '2015-05-20')
);
或
select *
from m_room
left join order_room
on m_room.room_id = order_room.room_id
and ('2015-05-16' between start_date and end_date - interval 1 day
or '2015-05-20' between start_date - interval 1 day and end_date
or start_date between '2015-05-16' and '2015-05-20')
where start_date is null;
关于php - SQL预订酒店房间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30206773/