Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL seleciona linhas onde a data não está entre a data


Supondo que você esteja interessado em colocar @Guests de @StartDate para @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

deve fornecer uma lista de todos os quartos que são gratuitos e podem acomodar um determinado número de hóspedes para o período determinado.

NOTAS
Esta consulta funciona apenas para quartos individuais, se você quiser ver vários quartos, precisará aplicar os mesmos critérios a uma combinação de quartos. Para isso, você precisaria de consultas recursivas ou algumas tabelas auxiliares. Além disso, o COALESCE está lá para cuidar dos NULLs - se um quarto não for reservado, ele não terá registros com datas para comparar, portanto, não retornará totalmente gratuito quartos. Date entre date1 e date2 retornará NULL se date1 ou date2 for nulo e coalesce o transformará em true (alternativa é fazer uma UNION de salas completamente livres; o que pode ser mais rápido).

Com várias salas, as coisas ficam realmente interessantes. Esse cenário é grande parte do seu problema? E qual banco de dados você está usando, ou seja, você tem acesso a consultas recursivas?

EDITAR

Como afirmei várias vezes antes, sua maneira de procurar uma solução (algoritmo ganancioso que analisa primeiro os maiores quartos gratuitos) não é a ideal se você deseja obter o melhor ajuste entre o número necessário de hóspedes e quartos.

Então, se você substituir seu foreach por
$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);

Passará por todas as combinações possíveis e encontre a solução que desperdiça o menor número de espaços.