Zakładając, że jesteś zainteresowany umieszczeniem @Guests
z @StartDate
do @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
powinien podać listę wszystkich wolnych pokoi, które mogą pomieścić określoną liczbę gości w danym okresie.
UWAGI
To zapytanie działa tylko dla pojedynczych pokoi, jeśli chcesz przejrzeć wiele pokoi, musisz zastosować te same kryteria do kombinacji pokoi. Do tego potrzebne byłyby zapytania rekurencyjne lub jakieś tabele pomocnicze. Ponadto COALESCE ma zająć się wartościami NULL - jeśli pokój nie jest w ogóle zarezerwowany, nie miałby żadnych rekordów z datami do porównania, więc nie wróciłby całkowicie za darmo pokoje. Data między data1 i data2 zwróci NULL, jeśli data1 lub data2 ma wartość NULL, a koalescencja zmieni ją na prawdę (alternatywą jest wykonanie UNION całkowicie wolnych pokoi; co może być szybsze).
Z wieloma pokojami robi się naprawdę ciekawie. Czy ten scenariusz jest dużą częścią twojego problemu? A jakiej bazy danych używasz, tj. czy masz dostęp do zapytań rekurencyjnych?
EDYTUJ
Jak już wielokrotnie mówiłem, Twój sposób poszukiwania rozwiązania (algorytm zachłanny, który najpierw sprawdza największe wolne pokoje) nie jest optymalny, jeśli chcesz uzyskać najlepsze dopasowanie między wymaganą liczbą gości i pokojami.
Tak więc, jeśli zamienisz foreach na
$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);
Przejrzy wszystkie możliwe kombinacje i znajdź rozwiązanie, które marnuje najmniej przestrzeni.