SQL预订酒店房间

时间:2015-05-13 05:58:03

标签: php mysql

我想使用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; start-> 2015-05-13; end-> 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

那么,如何修复我的查询以显示任何可用的房间?

4 个答案:

答案 0 :(得分:3)

我认为你可能采取了错误的做法。您想要查找整个期间可用的房间,这意味着如果有任何预订的开始日期或结束日期,包含您要查找的期间的开始日期或结束日期,则必须是拒绝。

我们可以使用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')
   );

demo here

作为第二个选项,您还可以left joinorder_room表,将日期范围放在连接条件中,然后检查order_room值为{{{1}的行1}}。

null

this demo也有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; 选项,显示结果相同。这种方法的优势在于您可以获得两个有意义的结果 - 它向您显示绝对可用的房间,如果您删除left join条款,它还会显示与其他房间冲突的预订时间。 / p>

如果您想在与其他预订退房/入住日重叠的同一天办理入住/退房手续,我们只需要将日期范围修改一天,如下所示:

where

OR

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')
   );

答案 1 :(得分:0)

房间ID 1将显示第二个查询,因为输入的结束日期在order_bookend之后,所以我想你需要检查我们之间输入的开始日期。预订开始和结束,或输入的结束日期在预订开始和结束之间

WHERE ('$start'>= order_bookstart OR '$start'< order_bookend) OR 
('$end'>= order_bookstart OR '$end'< order_bookend)

答案 2 :(得分:0)

考虑以下

  1 2 3 4 5 6 7 8 9 

A |---|

B    |-----|

C            |----|

D   |-----------|

重叠测试比pala简单,其他人似乎很欣赏。

事件B与事件A重叠,因为事件B在事件A结束之前开始,并在事件A开始之后结束。

事件C不会与事件B重叠,因为事件B在事件B开始后结束,但它在事件B结束后开始

事件D与所有其他事件重叠,因为事件D在所有其他事件结束之前开始,并在所有其他事件开始之后结束。

所以对重叠的测试很简单:

y_start < x_end AND y_end > x_start 

答案 3 :(得分:-1)

为了使房间不包含在搜索结果中,WHERE条件应涵盖以下情况:

a) bookstart----start--------bookend-------end------------

b) -------------start--------bookstart-----end-----bookend

c) -------------start--bookstart--bookend--end------------

d) bookstart----start----------------------end-----bookend

换句话说, bookstart bookend 介于开始结束之间(案例a-c) ,或 bookstart 开始之前,书挡结束之后(案例d):

所以正确的SQL应如下所示:

WHERE (order_bookstart >= $start AND order_bookstart < $end) OR
(order_bookend >= $start AND order_bookend < $end) OR 
(order_bookstart < $start AND order_bookend > $end)