Ако приемем, че проявявате интерес да поставите @Guests
от @StartDate
до @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
трябва да ви даде списък на всички стаи, които са безплатни и могат да настанят определен брой гости за дадения период.
БЕЛЕЖКИ
Тази заявка работи само за единични стаи, ако искате да разгледате няколко стаи, ще трябва да приложите същите критерии към комбинация от стаи. За това ще ви трябват рекурсивни заявки или помощни таблици. Освен това COALESCE е там, за да се погрижи за NULL - ако стаята изобщо не е резервирана, тя няма да има записи с дати за сравняване, така че няма да се върне напълно безплатно стаи. Датата между date1 и date2 ще върне NULL, ако или date1, или date2 са нула и coalesce ще я превърне в true (алтернатива е да направите UNION от напълно безплатни стаи; което може да е по-бързо).
С няколко стаи нещата стават наистина интересни. Този сценарий голяма част от проблема ви ли е? И коя база данни използвате, т.е. имате ли достъп до рекурсивни заявки?
РЕДАКТИРАНЕ
Както казах няколко пъти по-рано, вашият начин да търсите решение (алчен алгоритъм, който разглежда първо най-големите свободни стаи) не е оптималният, ако искате да постигнете най-доброто съответствие между необходимия брой гости и стаи.
Така че, ако замените вашия foreach с
$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);
Ще премине през всички възможни комбинации и намерете решението, което губи най-малък брой интервали.