En supposant que vous êtes intéressé à placer @Guests
de @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
devrait vous donner une liste de toutes les chambres qui sont libres et peuvent accueillir un nombre donné d'invités pour la période donnée.
REMARQUES
Cette requête ne fonctionne que pour les chambres individuelles. Si vous souhaitez consulter plusieurs chambres, vous devrez appliquer les mêmes critères à une combinaison de chambres. Pour cela, vous auriez besoin de requêtes récursives ou de tables d'assistance. En outre, COALESCE est là pour s'occuper des valeurs NULL - si une salle n'est pas du tout réservée, elle n'aurait aucun enregistrement avec des dates à comparer, elle ne reviendrait donc pas complètement gratuitement pièces. La date entre date1 et date2 renverra NULL si date1 ou date2 est nulle et coalesce la transformera en true (l'alternative consiste à faire une UNION de salles entièrement libres ; ce qui pourrait être plus rapide).
Avec plusieurs pièces, les choses deviennent vraiment intéressantes. Ce scénario fait-il partie de votre problème ? Et quelle base de données utilisez-vous, c'est-à-dire avez-vous accès aux requêtes récursives ?
MODIFIER
Comme je l'ai déjà dit à plusieurs reprises, votre façon de rechercher une solution (algorithme gourmand qui examine d'abord les plus grandes chambres libres) n'est pas optimale si vous souhaitez obtenir le meilleur ajustement entre le nombre requis d'invités et de chambres.
Donc, si vous remplacez votre foreach par
$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);
Passe en revue toutes les combinaisons possibles et trouvez la solution qui gaspille le moins d'espaces.