sql >> Databasteknik >  >> RDS >> Mysql

MySQL välj rader där datum inte mellan datum

Förutsatt att du är intresserad av att placera @Guests från @StartDate till @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

bör ge dig en lista över alla rum som är gratis och kan ta emot ett visst antal gäster för den givna perioden.

ANMÄRKNINGAR
Denna fråga fungerar endast för enkelrum, om du vill titta på flera rum måste du tillämpa samma kriterier på en kombination av rum. För detta skulle du behöva rekursiva frågor eller några hjälptabeller. Dessutom är COALESCE där för att ta hand om NULLs - om ett rum inte är bokat alls skulle det inte ha några poster med datum att jämföra med, så det skulle inte returnera helt gratis rum. Datum mellan datum1 och datum2 kommer att returnera NULL om antingen datum1 eller datum2 är null och sammansmältning kommer att göra det till sant (alternativet är att göra en UNION av helt fria rum, vilket kan vara snabbare).

Med flera rum blir saker riktigt intressanta. Är det scenariot en stor del av ditt problem? Och vilken databas använder du, dvs har du tillgång till rekursiva frågor?

REDIGERA

Som jag sagt flera gånger tidigare är ditt sätt att leta efter en lösning (girig algoritm som tittar på de största lediga rummen först) inte det optimala om du vill få den bästa passformen mellan det antal gäster och rum som krävs.

Så om du byter ut din foreach med

$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);

Går igenom alla möjliga kombinationer och hitta den lösning som slösar minst antal utrymmen.



  1. Laravel vältalig grupp enligt senaste skivan

  2. Infinite Scroll med MySQL Data

  3. SQL Server IF vs IIF():Vad är skillnaden?

  4. Hur man skapar en sekvens i MySQL