2014-04-05 164 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