如何向已经复杂的查询添加一个表

时间:2014-06-19 08:31:57

标签: mysql sql join

我正在尝试为酒店房间建立搜索查询,但似乎他的查询已经超出了我的想法,我需要帮助来构建它。 请注意,数据库中会有多个酒店。

即使我正在寻找可用的房间,我的想法不是建立可用的表,而是使用reserevation表, 我假设如果房间不在预订表中,则可以使用。

我在搜索表单中有以下字段:

区域(用areaid表示),checkInDate,checkOutDate,房间(他需要多少房间),成人和儿童。

以下是此搜索中应包含的表格:

房间类型预订房间预订和酒店

(对于那些为什么我有resrevation房间,原因很简单,一个预订可以有多个房间,所以它是帮助表)#/ p>

以下是表格:

CREATE TABLE `room` (
    `roomID` int(11) NOT NULL AUTO_INCREMENT,
    `hotelID` int(11) NOT NULL,
    `roomtypeID` int(11) NOT NULL,
    `roomNumber` int(11) NOT NULL,
    `roomName` varchar(255) NOT NULL,
    `roomDescription` text,
    `roomVisible` tinyint(4) NOT NULL,
    PRIMARY KEY (`roomID`),
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

CREATE TABLE `roomtype` (
    `roomtypeID` int(11) NOT NULL AUTO_INCREMENT,
    `hotelID` int(11) NOT NULL,
    `roomtypeName` varchar(255) NOT NULL,
    `roomtypeAdults` int(11) NOT NULL,
    `roomtypeChildrens` int(11) NOT NULL,
    `roomtypeDescription` text,
    PRIMARY KEY (`roomtypeID`),
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

CREATE TABLE `hotel` (
    `hotelID` int(11) NOT NULL AUTO_INCREMENT,
    `areaID` int(11) NOT NULL,
    `hotelcategoryID` int(11) DEFAULT NULL,
    `hotelName` varchar(255) NOT NULL,
    `hotelShortDescription` text,
    `hotelAddress` varchar(255) DEFAULT NULL
    PRIMARY KEY (`hotelID`),
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;


CREATE TABLE `reservation` (
    `reservationID` int(11) NOT NULL AUTO_INCREMENT,
    `customerID` int(11) NOT NULL,
    `hotelID` int(11) NOT NULL,
    `reservationCreatedOn` datetime NOT NULL,
    `reservationCreatedFromIp` varchar(255) CHARACTER SET greek NOT NULL,
    `reservationNumberOfAdults` tinyint(4) NOT NULL,
    `reservationNumberOfChildrens` tinyint(4) NOT NULL,
    `reservationArrivalDate` date NOT NULL,
    `reservationDepartureDate` date NOT NULL,
    `reservationCustomerComment` text CHARACTER SET greek,
    PRIMARY KEY (`reservationID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE `reservationroom` (
    `reservationroomID` int(11) NOT NULL AUTO_INCREMENT,
    `reservationID` int(11) NOT NULL,
    `hotelID` int(11) NOT NULL,
    `roomID` int(11) NOT NULL,
    PRIMARY KEY (`reservationroomID`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

请注意,我已从表格中删除了不必要的字段,以使代码更短,更易于阅读。

此时,我有以下查询可行,但问题是我必须在此查询中包含预订表,  考虑到我的搜索有2个字段checkInDate,checkOutDate这是检查哪些酒店有空房的主要参数。

以下是当前查询:

    SELECT r.*, h.*,rr.* FROM room r 
LEFT JOIN `reservationroom` rr 
ON r.`hotelID` = rr.`hotelID` AND r.`roomID` = rr.`roomID`
LEFT JOIN `hotel` h
ON h.`hotelID` = r.`hotelID` 
WHERE ( rr.`reservationroomID` = '' OR rr.`reservationroomID` IS  NULL );

任何人都可以帮我在此查询中添加预订表吗?

问候,约翰

1 个答案:

答案 0 :(得分:1)

主要问题是从搜索中消除房间是保留的。为此,您需要加入预订表并检查日期范围是否与预订范围重叠。

基本原理是: -

SELECT r.*, h.*,rr.* 
FROM room r 
INNER JOIN `hotel` h
ON h.`hotelID` = r.`hotelID` 
LEFT JOIN `reservationroom` rr 
ON r.`hotelID` = rr.`hotelID` 
AND r.`roomID` = rr.`roomID`
LEFT JOIN reservation res
ON  rr.reservationID = res.reservationID
AND res.reservationArrivalDate < $checkOutDate
AND res.reservationDepartureDate > $checkInDate
WHERE ( rr.`reservationroomID` = '' 
OR rr.`reservationroomID` IS  NULL );

当您需要检查可用房间数时,它会变得更加复杂。要做到这一点,您可能需要使用与上述类似的东西作为子查询,获取酒店ID和房间数,然后使用HAVING检查计数是否大于或等于所需的房间数,然后加入结果对酒店和客房的反对,以获得可用房间的所需细节。

编辑 - 更多细节(未经测试)。子查询在需要的时间内获得足够的免费房间的酒店,然后加入酒店和房间以获取详细信息。

SELECT r.*, h.*
FROM room r 
INNER JOIN hotel h
ON h.hotelID = r.hotelID 
INNER JOIN
(
    SELECT h.hotelID, COUNT(r.roomID) AS RoomCount
    FROM room r 
    INNER JOIN hotel h
    ON h.hotelID = r.hotelID 
    LEFT JOIN reservationroom rr 
    ON r.hotelID = rr.hotelID 
    AND r.roomID = rr.roomID
    LEFT JOIN reservation res
    ON  rr.reservationID = res.reservationID
    AND res.reservationArrivalDate < $checkOutDate
    AND res.reservationDepartureDate > $checkInDate
    WHERE ( res.reservationID IS  NULL )
    AND h.areaID = $areaID
    GROUP BY h.hotelID
    HAVING RoomCount >= $rooms
) sub0
ON h.hotelID = sub0.hotelID