Za předpokladu, že máte zájem umístit @Guests
z @StartDate
na @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
by vám měl poskytnout seznam všech pokojů, které jsou volné a mohou ubytovat daný počet hostů na dané období.
POZNÁMKY
Tento dotaz funguje pouze pro jednolůžkové pokoje, pokud se chcete podívat na více pokojů, budete muset použít stejná kritéria pro kombinaci pokojů. K tomu byste potřebovali rekurzivní dotazy nebo nějaké pomocné tabulky. COALESCE je tu také od toho, aby se postaral o NULL – pokud místnost není vůbec zarezervována, nebude mít žádné záznamy s daty, se kterými by bylo možné porovnávat, takže by se nevrátila zcela zdarma pokoje. Datum mezi datem1 a date2 vrátí NULL, pokud je datum1 nebo datum2 null a sloučením se změní na true (alternativou je vytvořit UNION zcela volných místností; což může být rychlejší).
S více místnostmi jsou věci opravdu zajímavé. Je tento scénář velkou součástí vašeho problému? A jakou databázi používáte, tj. máte přístup k rekurzivním dotazům?
UPRAVIT
Jak jsem již několikrát uvedl, váš způsob hledání řešení (chamtivý algoritmus, který se nejprve podívá na největší volné pokoje) není optimální, pokud chcete dosáhnout nejlepšího souladu mezi požadovaným počtem hostů a pokoji.
Pokud tedy nahradíte foreach za
$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);
Projde všemi možnými kombinacemi a najděte řešení, které plýtvá co nejmenším počtem míst.