Supponendo che tu sia interessato a inserire @Guests
da @StartDate
a @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
dovrebbe darti un elenco di tutte le camere che sono libere e possono ospitare un determinato numero di ospiti per un determinato periodo.
NOTE
Questa query funziona solo per stanze singole, se vuoi guardare più stanze dovrai applicare gli stessi criteri a una combinazione di stanze. Per questo avresti bisogno di query ricorsive o di alcune tabelle di supporto. Inoltre, COALESCE è lì per prendersi cura dei NULL - se una stanza non è stata prenotata non avrebbe alcun record con date da confrontare, quindi non sarebbe completamente gratuita camere. La data tra date1 e date2 restituirà NULL se date1 o date2 sono nulle e coalescente lo trasformerà in true (l'alternativa è fare un'UNIONE di stanze completamente libere; il che potrebbe essere più veloce).
Con più stanze le cose si fanno davvero interessanti. Quello scenario è una parte importante del tuo problema? E quale database stai utilizzando, ad esempio hai accesso a query ricorsive?
MODIFICA
Come ho affermato più volte in precedenza, il tuo modo di cercare una soluzione (algoritmo avido che esamina prima le camere libere più grandi) non è ottimale se vuoi ottenere il miglior adattamento tra il numero richiesto di ospiti e le camere.
Quindi, se sostituisci il tuo foreach con
$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);
Esaminerà tutte le possibili combinazioni e trova la soluzione che spreca il minor numero di spazi.