【问题标题】:Checking the availability of rooms检查房间的可用性
【发布时间】:2018-06-23 01:33:41
【问题描述】:

我的 sql 数据库中有 3 个表:

Table Room

roomnumber   roomtype    
  1           DeluxeRoom           
  2           DeluxeRoom  
  3           DeluxeRoom
  100         StandardRoom           
  101         StandardRoom  
  102         StandardRoom

Room 是一个存储房间及其类型的表。

Table Reservation

reservationid  checkin       checkout
  1           2017-01-01     2017-01-03
  2           2017-01-10     2017-01-20
  3           2017-02-05     2017-02-08

Reservation 是用户进行预订的表格。

Table RoomReserve

reservationid    roomnumber
 1                 1
 2                 100
 2                 101
 3                 1
 3                 2
 3                 3

在 RoomReserve 中,对于每个预订 ID,我可以为房间号输入多个值。如果入住日期和退房日期不一样,我也可以为不同的预订ID输入相同的房间号。

当用户想要预订房间但我得到的结果错误时,我正在尝试在 php 中进行查询以计算可用房间。

这是我正在尝试的代码:

 1) $sql="SELECT COUNT(roomnumber) FROM room WHERE roomtype='DeluxeRoom'  AND roomnumber NOT IN ( 
SELECT * FROM roomreserve r,reservation e, room m  WHERE r.reservation_id=e.reservation_id AND m.roomnumber=r.roomnumber
AND ('$checkin' BETWEEN start_date AND end_date) OR ('$checkout' BETWEEN start_date AND end_date))"; 

2) $sql="SELECT COUNT(roomnumber) FROM room WHERE roomtype='DeluxeRoom'  AND roomnumber NOT IN ( 
SELECT COUNT(roomnumber) FROM roomreserve r,reservation e, room m  WHERE r.reservation_id=e.reservation_id AND m.roomnumber=r.roomnumber
AND ('$checkin' BETWEEN start_date AND end_date) OR ('$checkout' BETWEEN start_date AND end_date))"; 

【问题讨论】:

  • 如果您不知道答案,请不要标记问题。
  • 尝试扩展一下短语“我正在尝试在 php 中查询...
  • 您需要分解问题。它与PHP相关吗?部分查询有效吗?问题是BETWEEN 还是reservation_id?查询中的字段名称与数据中的字段名称不匹配,SELECT *roomnumber NOT IN 子句不匹配。从一个较小的问题开始,然后从那里开始。
  • 你怎么知道哪个用户预订了哪个房间?
  • 如果我预订了 2 间房间,一间给我,一间给我的朋友,但我的朋友比我早一天到达,一天后离开怎么办?

标签: php mysql sql


【解决方案1】:

你绝不会说你所拥有的有什么问题,但假设问题是语法上的(即你根本无法执行语句),然后试试这个:

SET @start_date = '2017-01-01';
SET @end_date = '2017-01-10';
SELECT COUNT(roomnumber) FROM room WHERE roomtype='DeluxeRoom'  AND roomnumber NOT IN ( 
SELECT r.roomnumber FROM roomreserve r,reservation e, room m  WHERE r.reservationid=e.reservationid AND m.roomnumber=r.roomnumber
AND ((checkin BETWEEN @start_date AND @end_date) OR (checkout BETWEEN @start_date AND @end_date)));

至少这是一个有效的 SQL 语句。根据需要将其包装在 PHP 中。

完整的 c&p 测试用例:

DROP TABLE Room;
DROP TABLE Reservation;
DROP TABLE RoomReserve;

CREATE TABLE Room (
    roomnumber int,
    roomtype varchar(255)
);

INSERT INTO Room
VALUES
    (1, 'DeluxeRoom'),
    (2, 'DeluxeRoom'),
    (3, 'DeluxeRoom'),
    (100, 'StandardRoom'),
    (101, 'StandardRoom'),
    (102, 'StandardRoom');


CREATE TABLE Reservation (
    reservationid int,
    checkin date,
    checkout date
);

INSERT INTO Reservation
VALUES
    (1, '2017-01-01', '2017-01-03'),
    (2, '2017-01-10', '2017-01-20'),
    (3, '2017-02-05', '2017-02-08');

CREATE TABLE RoomReserve (
    reservationid int,
    roomnumber int
);

INSERT INTO RoomReserve
VALUES
    (1, 1),
    (2, 100),
    (2, 101),
    (3, 1),
    (3, 2),
    (3, 3);


SET @start_date = '2017-01-01';
SET @end_date = '2017-01-10';

SELECT COUNT(roomnumber) FROM room WHERE roomtype='DeluxeRoom'  AND roomnumber NOT IN ( 
SELECT r.roomnumber FROM roomreserve r,reservation e, room m  WHERE r.reservationid=e.reservationid AND m.roomnumber=r.roomnumber
AND ((checkin BETWEEN @start_date AND @end_date) OR (checkout BETWEEN @start_date AND @end_date)));

我得到“2”作为响应,这是在 2017-01-01 和 2017-01-10(房间 2 和 3)之间没有预订日期的 DeluxeRoom 的数量。

【讨论】:

  • 您的日期比较逻辑错误且过于复杂。
  • 您的评论是否出现在错误的位置?这是 OP 的逻辑,不是我的。
  • 操作员想知道如何检查房间可用性,因此给定答案可能会尝试解决该问题似乎是合理的
  • 似乎你错过了第一句话,“但假设问题是句法的”。所需的逻辑没有明确表达到足以解决它,同时答案中的逻辑做了一些可以合理预期有用的事情,(即返回在 start_date 和 end_date 之间没有预订日期的 DeluxeRoom 的数量) .过早的优化是万恶之源等
【解决方案2】:

如果客户当前已入住房间,结帐栏中的内容是什么?如果它为空,那么您可以使用checkout is null 进行查询或根据您认为合适的方式修改该部分。

select count(*) from room where roomtype = 'DeluxeRoom' and roomnumber not in (
select room.roomnumber from room, reservation, roomreserve where room.roomtype = 'DeluxeRoom' and roomreserve.roomnumber = room.roomnumber and roomreserve.reservationid = reservation.reservationid and checkout is null)

您还可以在 Reservation 表中添加一个 check_out 标志,以使您的查询更容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 2012-06-03
    • 2019-07-16
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多