如何简化有关预订的查询?

时间:2018-06-12 07:15:19

标签: php mysql

我有酒店预订系统,当用户输入新的预订日期时,我需要检索所有未预订的房间,

预订表包含room_id,startdate,period

我写了这个查询,只需要简化它

select * 
from rooms 
where id in (
   select room_id 
   from reservations 
   where '2018-6-11' not BETWEEN date_at and date_add(date_at, INTERVAL period day) 
   and '2018-6-30' not between date_at and date_add(date_at, INTERVAL period day) 
   and date_at not between '2018-6-11' and '2018-6-30' 
   and date_add(date_at ,INTERVAL period day ) not between '2018-6-11' and '2018-6-30' ) 
or id not in (select room_id from reservations)

3 个答案:

答案 0 :(得分:1)

如何将IN子句转换为等效连接?如果它适用于您的情况,请参阅以下查询:

SELECT *
FROM rooms rm
JOIN 
   (SELECT room_id rmid
  FROM reservations
  WHERE '2018-6-11' NOT BETWEEN date_at AND date_add(date_at, INTERVAL period DAY)
  AND '2018-6-30' NOT BETWEEN date_at AND date_add(date_at, INTERVAL period DAY)
  AND date_at NOT BETWEEN '2018-6-11' AND '2018-6-30'
  AND date_add(date_at ,INTERVAL period DAY ) NOT BETWEEN '2018-6-11' AND '2018-6-30'
  ) tb1  
ON  rm.ID = tb.rmid 
JOIN reservations rv
ON rm.ID <> rv.room_id;

答案 1 :(得分:0)

让我们将其分解为2个子问题。

  • 获取所有从未预订的房间。
  • 让所有房间永远不会与预订的客房发生冲突。时序。

在查询中,我假设$start_date$end_date是PHP变量,其中存储了用户选择的值。

(select * 
from rooms where room_id NOT IN (select room_id from reservations))

UNION

(select *
from rooms where room_id IN (
   select room_id 
   from reservations 
   where $start_date not BETWEEN date_at and date_add(date_at, INTERVAL period day) 
   and $end_date not between date_at and date_add(date_at, INTERVAL period day)
   and ($start_date > date_add(date_at, INTERVAL period day) OR $end_date < date_at)
))

答案 2 :(得分:0)

您不需要进行2次IN次查询。 由于在您的第一个IN查询中,您只有NOT个子句,因此可以将这些子句更改为NOT IN并删除子查询中的NOT。 这也将删除第二个OR IN

select * 
from rooms 
where id not in (
   select room_id 
   from reservations 
   where '2018-6-11' BETWEEN date_at and date_add(date_at, INTERVAL period day) 
   or '2018-6-30' between date_at and date_add(date_at, INTERVAL period day)
   or date_at between '2018-6-11' and '2018-6-30' 
   or date_add(date_at ,INTERVAL period day ) between '2018-6-11' and '2018-6-30' )) 

此查询基本上转换为: 给我所有没有预订的房间,我的开始日期或结束日期在预订时间之间。

修改

感谢@ vivek_23我意识到查询不能简化内部条件 - 尽管如此,这个版本将对数据库的查询量减少到2个。