sql >> Base de Datos >  >> RDS >> Mysql

MySQL selecciona filas donde la fecha no está entre la fecha

Suponiendo que esté interesado en colocar @Guests de @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

debe darle una lista de todas las habitaciones que están libres y pueden acomodar un número determinado de huéspedes durante el período determinado.

NOTAS
Esta consulta solo funciona para habitaciones individuales, si desea ver varias habitaciones, deberá aplicar los mismos criterios a una combinación de habitaciones. Para esto, necesitaría consultas recursivas o algunas tablas de ayuda. Además, COALESCE está ahí para encargarse de los NULL:si una habitación no está reservada, no tendrá ningún registro con fechas para comparar, por lo que no regresará completamente gratis. habitaciones. La fecha entre la fecha 1 y la fecha 2 devolverá NULL si la fecha 1 o la fecha 2 son nulas y coalesce la convertirá en verdadera (la alternativa es hacer una UNIÓN de salas completamente libres, lo que podría ser más rápido).

Con múltiples habitaciones, las cosas se vuelven realmente interesantes. ¿Es ese escenario una gran parte de su problema? ¿Y qué base de datos está utilizando, es decir, tiene acceso a consultas recursivas?

EDITAR

Como dije varias veces antes, su forma de buscar una solución (algoritmo codicioso que busca primero las habitaciones libres más grandes) no es la óptima si desea obtener el mejor ajuste entre el número requerido de huéspedes y habitaciones.

Entonces, si reemplaza su 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);

Pasará por todas las combinaciones posibles y encuentre la solución que desperdicie la menor cantidad de espacios.