Giả sử rằng bạn muốn đặt @Guests
từ @StartDate
đến @EndDate
SELECT DISTINCT r.id,
FROM room r
LEFT JOIN roombooking_room rbr ON r.id = rbr.room_id
LEFT JOIN roombooking ON rbr.roombooking_id = rb.id
WHERE COALESCE(@StartDate NOT BETWEEN rb.startDate AND rb.endDate, TRUE)
AND COALESCE(@EndDate NOT BETWEEN rb.startDate AND rb.endDate, TRUE)
AND @Guests < r.maxGuests
sẽ cung cấp cho bạn danh sách tất cả các phòng miễn phí và có thể chứa số lượng khách nhất định trong khoảng thời gian nhất định.
LƯU Ý
Truy vấn này chỉ hoạt động cho các phòng đơn, nếu bạn muốn xem nhiều phòng, bạn sẽ cần áp dụng cùng một tiêu chí cho một tổ hợp các phòng. Đối với điều này, bạn sẽ cần truy vấn đệ quy hoặc một số bảng trợ giúp Ngoài ra, COALESCE luôn ở đó để chăm sóc NULL - nếu một phòng chưa được đặt trước, nó sẽ không có bất kỳ bản ghi nào với ngày để so sánh, vì vậy nó sẽ không hoàn toàn miễn phí. phòng. Ngày giữa date1 và date2 sẽ trả về NULL nếu date1 hoặc date2 là null và việc kết hợp với nhau sẽ biến nó thành true (thay thế là tạo một UNION các phòng hoàn toàn miễn phí; có thể nhanh hơn).
Với nhiều phòng, mọi thứ trở nên thực sự thú vị. Và bạn đang sử dụng cơ sở dữ liệu nào, tức là bạn có quyền truy cập vào các truy vấn đệ quy không?
CHỈNH SỬA
Như tôi đã nói nhiều lần trước đây, cách bạn tìm kiếm giải pháp (thuật toán tham lam xem xét các phòng trống lớn nhất trước tiên) không phải là tối ưu nếu bạn muốn có được sự phù hợp nhất giữa số lượng khách và phòng yêu cầu.
Vì vậy, nếu bạn thay thế foreach của mình bằng
$bestCapacity = 0;
$bestSolution = array();
for ($i = 1; $i <= pow(2,sizeof($result))-1; $i++) {
$solutionIdx = $i;
$solutionGuests = 0;
$solution = array();
$j = 0;
while ($solutionIdx > 0) :
if ($solutionIdx % 2 == 1) {
$solution[] = $result[$j]['id'];
$solutionGuests += $result[$j]['maxGuests'];
}
$solutionIdx = intval($solutionIdx/2);
$j++;
endwhile;
if (($solutionGuests <= $bestCapacity || $bestCapacity == 0) && $solutionGuests >= $noGuests) {
$bestCapacity = $solutionGuests;
$bestSolution = $solution;
}
}
print_r($bestSolution);
print_r($bestCapacity);
Sẽ đi qua tất cả các kết hợp có thể có và tìm giải pháp lãng phí ít khoảng trắng nhất.