Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL sélectionne les lignes où la date n'est pas entre les dates

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.