Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL wybierz wiersze, w których data nie znajduje się między datą

Zakładając, że jesteś zainteresowany umieszczeniem @Guests z @StartDate do @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

powinien podać listę wszystkich wolnych pokoi, które mogą pomieścić określoną liczbę gości w danym okresie.

UWAGI
To zapytanie działa tylko dla pojedynczych pokoi, jeśli chcesz przejrzeć wiele pokoi, musisz zastosować te same kryteria do kombinacji pokoi. Do tego potrzebne byłyby zapytania rekurencyjne lub jakieś tabele pomocnicze. Ponadto COALESCE ma zająć się wartościami NULL - jeśli pokój nie jest w ogóle zarezerwowany, nie miałby żadnych rekordów z datami do porównania, więc nie wróciłby całkowicie za darmo pokoje. Data między data1 i data2 zwróci NULL, jeśli data1 lub data2 ma wartość NULL, a koalescencja zmieni ją na prawdę (alternatywą jest wykonanie UNION całkowicie wolnych pokoi; co może być szybsze).

Z wieloma pokojami robi się naprawdę ciekawie. Czy ten scenariusz jest dużą częścią twojego problemu? A jakiej bazy danych używasz, tj. czy masz dostęp do zapytań rekurencyjnych?

EDYTUJ

Jak już wielokrotnie mówiłem, Twój sposób poszukiwania rozwiązania (algorytm zachłanny, który najpierw sprawdza największe wolne pokoje) nie jest optymalny, jeśli chcesz uzyskać najlepsze dopasowanie między wymaganą liczbą gości i pokojami.

Tak więc, jeśli zamienisz foreach na

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

Przejrzy wszystkie możliwe kombinacje i znajdź rozwiązanie, które marnuje najmniej przestrzeni.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak poprawnie zapisywać ciągi znaków UTF-8 w MySQL za pomocą interfejsu JDBC?

  2. Manipulowanie danymi utf8mb4 z MySQL za pomocą PHP

  3. Problem ze zmienną zwracaną w bash

  4. Tworzenie tablicy za pomocą rekurencyjnego php z mysql

  5. Numer wiersza na grupę w mysql