Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL избира редове, където датата не е между датата

Ако приемем, че проявявате интерес да поставите @Guests от @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

трябва да ви даде списък на всички стаи, които са безплатни и могат да настанят определен брой гости за дадения период.

БЕЛЕЖКИ
Тази заявка работи само за единични стаи, ако искате да разгледате няколко стаи, ще трябва да приложите същите критерии към комбинация от стаи. За това ще ви трябват рекурсивни заявки или помощни таблици. Освен това COALESCE е там, за да се погрижи за NULL - ако стаята изобщо не е резервирана, тя няма да има записи с дати за сравняване, така че няма да се върне напълно безплатно стаи. Датата между date1 и date2 ще върне NULL, ако или date1, или date2 са нула и coalesce ще я превърне в true (алтернатива е да направите UNION от напълно безплатни стаи; което може да е по-бързо).

С няколко стаи нещата стават наистина интересни. Този сценарий голяма част от проблема ви ли е? И коя база данни използвате, т.е. имате ли достъп до рекурсивни заявки?

РЕДАКТИРАНЕ

Както казах няколко пъти по-рано, вашият начин да търсите решение (алчен алгоритъм, който разглежда първо най-големите свободни стаи) не е оптималният, ако искате да постигнете най-доброто съответствие между необходимия брой гости и стаи.

Така че, ако замените вашия foreach с

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

Ще премине през всички възможни комбинации и намерете решението, което губи най-малък брой интервали.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. какви са промените в случай на набор от редове на mysql 8?

  2. SQL:Връщане на най-често срещаната стойност за всеки човек

  3. Sequelize — използвайте времеви печат на UNIX за полета DATE

  4. Как да направя това в Laravel, подзаявка къде в

  5. Не може да се промени колоната, използвана в ограничение за външен ключ