结合两个SQL查询PDO

时间:2014-04-05 16:47:32

标签: php mysql sql pdo

我完全坚持以下问题。我有一系列表格: Image of the tables for convenience

我想要做的是获取房间的所有信息,假设预订金额不超过该房间的可用房间数。

所以要获取我的房间详细信息我的SQL是这样的:

  SELECT Rooms.RoomID as RoomID,
         RoomName, NumOfRooms, 
         MaxPeopleExistingBeds, 
         MaxExtraBeds, 
         MaxExtraPeople, 
         CostPerExtraPerson, 
         MaximumFreeChildren, 
         IncludeBreakfast, 
         MinRate 
    FROM Rooms, RoomDetails 
   WHERE Rooms.AccommodationID = :aid AND 
         Rooms.RoomID = RoomDetails.RoomID 
GROUP BY RoomName

返回时,我会获得这些房间的详细信息列表,如下所示: enter image description here

然后我使用此查询来获取预订的数量和房间的ID:

  SELECT Booking.RoomID, 
         count(Booking.RoomID) as Bookings  
    FROM Booking 
   WHERE ArriveDate >= :aDate AND 
         DepartDate <= :dDate AND 
         AccommodationID = :aid 
GROUP BY RoomID

然后我将这两个数组合并使用此函数将两个数组反馈到一个数组中:

public function get_availability($aid, $aDate, $dDate) {
        $stmt = $this->db->prepare('SELECT Rooms.RoomID as RoomID, RoomName, NumOfRooms, MaxPeopleExistingBeds, MaxExtraBeds, MaxExtraPeople, CostPerExtraPerson, MaximumFreeChildren, IncludeBreakfast, MinRate FROM Rooms, RoomDetails WHERE Rooms.AccommodationID = :aid AND Rooms.RoomID = RoomDetails.RoomID GROUP BY RoomName');
        $stmt->bindValue(':aid', $aid);
        $stmt->execute();
        $rooms = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $stmt2 = $this->db->prepare('SELECT Booking.RoomID, count(Booking.RoomID) as Bookings  FROM Booking WHERE ArriveDate >= :aDate AND DepartDate <= :dDate AND AccommodationID = :aid GROUP BY RoomID');
        $stmt2->bindValue(':aid', $aid);
        $stmt2->bindValue(':aDate', $aDate);
        $stmt2->bindValue(':dDate', $dDate);
        $stmt2->execute();
        $bookings = $stmt2->fetchAll(PDO::FETCH_ASSOC);
        $room = array($rooms, $bookings);

        return (!empty($room)) ? $room : false;
    }

问题是,我真正想做的只是返回NumOfRooms小于预订数量的房间细节。

所以例如我有$ bookings,如果它告诉我4号房间,我有3个预订一段时间,我的NumOfRooms是1.然后我知道我那个星期没有能力接受更多预订。但是,如果我有1个预订和一个容量,那么仍然是满的。但如果我的NumOfRooms为2,预订金额为1,我知道我有空间。

所以基本上如果NumOfRooms&gt; BookingCount然后房间可用。

如何合并查询并简化我的代码才能实现这一目标?

I.E简单地说,如何在预订中给出ArriveDate以及DepartDate和RoomID,从RoomDetails中选择所有信息,其中NumOfRooms&gt; count(Booking.RoomID)(在这些日期内,房间ID等于房间的房间ID)。

2 个答案:

答案 0 :(得分:2)

只需更新SQL语句本身即可解决您的问题:

SELECT r.RoomID AS RoomID,
       RoomName,
       NumOfRooms,
       MaxPeopleExistingBeds,
       MaxExtraBeds,
       MaxExtraPeople,
       CostPerExtraPerson,
       MaximumFreeChildren,
       IncludeBreakfast,
       MinRate
FROM Rooms r
JOIN RoomDetails rd
    ON r.RoomID = rd.RoomID
JOIN (
    SELECT b.RoomID,
           AccommodationID,
           count(b.RoomID) AS Bookings
    FROM Booking b
    WHERE ArriveDate >= :aDate
      AND DepartDate <= :dDate
    GROUP BY RoomID
) t
    ON t.AccommodationID = r.AccommodationID
WHERE r.AccommodationID = :aid
    AND t.Bookings < NumOfRooms
GROUP BY RoomName

答案 1 :(得分:0)

您可以选择每个房间的所有预订点数作为子查询的所需日期范围,然后LEFT JOIN针对您所希望的AccommodationID所需房间列表的子查询和所需的NumOfRooms > BookingCount条件。这里的关键是用于此子查询的连接类型,因为内部连接会将结果限制为仅实际预订的房间。

    SELECT Rooms.RoomID as RoomID,
           RoomName, NumOfRooms, 
           MaxPeopleExistingBeds, 
           MaxExtraBeds, 
           MaxExtraPeople, 
           CostPerExtraPerson, 
           MaximumFreeChildren, 
           IncludeBreakfast, 
           MinRate,
           BookingCount
      FROM Rooms
INNER JOIN RoomDetails on Rooms.RoomID = RoomDetails.RoomID
 LEFT JOIN (
               SELECT Booking.RoomID,
                      count(Booking.RoomID) as BookingCount
                 FROM Booking 
                WHERE ArriveDate >= :aDate AND 
                      DepartDate <= :dDate
             GROUP BY Booking.RoomID
           ) RoomBookings ON Rooms.RoomID = RoomBookings.RoomID
     WHERE Rooms.AccommodationID = :aid
       AND NumOfRooms > BookingCount
  GROUP BY RoomName