我有一個預訂系統,我需要從數據庫中選擇任何可用的房間。基本設置是:MySQL選擇日期不在日期之間的行
table: room
columns: id, maxGuests
table: roombooking
columns: id, startDate, endDate
table: roombooking_room:
columns: id, room_id, roombooking_id
,我需要選擇的客房,可容納請求的客人,或選擇兩個(或更多)的房間,以適應賓客(由maxGuests定義,顯然用最低/壁櫥maxGuests第一)
我可以遍歷我的日期範圍,並使用此SQL:
SELECT `id`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`, `roombooking`
WHERE `roombooking`.`confirmed` =1
AND DATE(%s) BETWEEN `roombooking`.`startDate` AND `roombooking`.`endDate`
)
AND `room`.`maxGuests`>=%d
其中,%$ 1是環狀日期%2d是在被預訂的客人數量,但這將只是如果有多於任何房間的客人可以返回假,並且必須有一個quic更好的方式做到這一點,而不是循環與PHP和運行查詢?
這類似於SQL的一部分,我想的是:Getting Dates between a range of dates但與MySQL
解決方案的基礎上,ircmaxwell的回答是:
$query = sprintf(
"SELECT `id`, `maxGuests`
FROM `room`
WHERE `id` NOT IN
(
SELECT `roombooking_room`.`room_id`
FROM `roombooking_room`
JOIN `roombooking` ON `roombooking_room`.`roombooking_id` = `roombooking`.`id`
WHERE `roombooking`.`confirmed` =1
AND (`roomBooking`.`startDate` > DATE(%s) OR `roomBooking`.`endDate` < DATE(%s))
)
AND `maxGuests` <= %d ORDER BY `maxGuests` DESC",
$endDate->toString('yyyy-MM-dd'), $startDate->toString('yyyy-MM-dd'), $noGuests);
$result = $db->query($query);
$result = $result->fetchAll();
$rooms = array();
$guests = 0;
foreach($result as $res) {
if($guests >= $noGuests) break;
$guests += (int)$res['maxGuests'];
$rooms[] = $res['id'];
}
爲什麼你有一個單獨的roombooking_room表?不應該tablerooming:id,room_id,startDate,endDate是否夠了? – Axarydax 2010-11-12 14:44:21
我認爲,爲了實現目標,對於想要實現的目標而言,執行所需任務所需的SQL會過於複雜。循環和使用PHP有什麼問題?您也可能會發現,如果您使用純SQL實現期望的結果,則該解決方案實際上可能比用PHP循環更慢。但是,我對看到結果非常感興趣,因爲我有時會發現自己提出了一個類似的問題(PHP vs SQL)。 – 2010-11-12 15:01:22
@Axaryday請在下面看到關於答案的評論。這是必要的,因爲一個預訂週期可能有多個房間關聯。即,我住10人,一個房間可以帶6人,因此我需要兩個房間,但在相同的預訂 – Ashley 2010-11-12 15:50:58