Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL seleziona le righe in cui la data non è compresa tra la data

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.