2014-04-05 189 views
1

我很困扰以下问题。我有一系列的表格: Image of the tables for convenience结合两个SQL查询PDO

我想要做的是获得一个房间的所有信息,假设预订量不超过该房间的可用房间数量。

因此,要获得我的房间详情我的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 

我再结合两者,并使用THI两个阵列反馈在一个阵列中S功能:

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小于预订数。

因此,例如,如果我预订了$预订,如果它告诉我对于ID号为4的房间,我有3次预订,而我的NumOfRooms为1,那么我知道我没有这周的容量任何更多的预订。但是,如果我有一个预订和一个容量,那么它仍然是满的。但是,如果我的NumOfRoom为2,并且预订达到1,我知道我有空间。

所以基本上如果NumOfRooms> BookingCount那么空间可用。

我怎么能合并查询和简化我的代码,以使这一切成为可能?

IE把它简单地说,我如何从BookingDetails中选择所有的信息,并给出一个DepartDate和RoomID,其中NumOfRooms> count(Booking.RoomID)(它在这些日期和房间号等于房间的房间号)。

+1

offtopic:请问什么是用来生成该SQL映像的? – phoops

+0

有点遗憾?这些表格是在Visio中创建的,SQL是输入的,Array是从chrome的控制台输入的。使用Puush剪切出我想要的部分屏幕(ctrl + shift + 4)。这是所有的图像占,因为我不知道你指的是:) –

回答

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 
+0

谢谢你的回答。 sql没有第三次连接,但第三次连接中的查询没有所有其他sql,但它们不能一起工作。我认为某个地方的逻辑存在缺陷。第三个内部联接返回例如4个RoomID和他们的预订。如果在该期间没有为该RoomID预订,则不会有条目。我发现如果我改变和t。预订 =或>它会显示所有内容,但不会显示<。我有的房间表中有9个房间的房间,在RoomDetails中有相应的细节。 –

+0

因此,如果客房数量不超过预订数量,则不会显示。问题出现在这个时期,即使没有预订,也没有显示。 –

+1

@DavidG你能提供有关sqlfiddle的示例数据吗? – hjpotter92

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