Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL chọn các hàng không có ngày giữa ngày

Giả sử rằng bạn muốn đặt @Guests từ @StartDate đến @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

sẽ cung cấp cho bạn danh sách tất cả các phòng miễn phí và có thể chứa số lượng khách nhất định trong khoảng thời gian nhất định.

LƯU Ý
Truy vấn này chỉ hoạt động cho các phòng đơn, nếu bạn muốn xem nhiều phòng, bạn sẽ cần áp dụng cùng một tiêu chí cho một tổ hợp các phòng. Đối với điều này, bạn sẽ cần truy vấn đệ quy hoặc một số bảng trợ giúp Ngoài ra, COALESCE luôn ở đó để chăm sóc NULL - nếu một phòng chưa được đặt trước, nó sẽ không có bất kỳ bản ghi nào với ngày để so sánh, vì vậy nó sẽ không hoàn toàn miễn phí. phòng. Ngày giữa date1 và date2 sẽ trả về NULL nếu date1 hoặc date2 là null và việc kết hợp với nhau sẽ biến nó thành true (thay thế là tạo một UNION các phòng hoàn toàn miễn phí; có thể nhanh hơn).

Với nhiều phòng, mọi thứ trở nên thực sự thú vị. Và bạn đang sử dụng cơ sở dữ liệu nào, tức là bạn có quyền truy cập vào các truy vấn đệ quy không?

CHỈNH SỬA

Như tôi đã nói nhiều lần trước đây, cách bạn tìm kiếm giải pháp (thuật toán tham lam xem xét các phòng trống lớn nhất trước tiên) không phải là tối ưu nếu bạn muốn có được sự phù hợp nhất giữa số lượng khách và phòng yêu cầu.

Vì vậy, nếu bạn thay thế foreach của mình bằng

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

Sẽ đi qua tất cả các kết hợp có thể có và tìm giải pháp lãng phí ít khoảng trắng nhất.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách xóa các ký tự đứng đầu và theo sau trong MySQL

  2. Có cách nào để biết tên người dùng hiện tại của bạn trong mysql không?

  3. Khi cập nhật khóa trùng lặp - Nhiều cột

  4. Lợi thế của việc sử dụng try {} catch {} so với if {} else {} là gì

  5. Xóa tất cả các hàng trùng lặp ngoại trừ một hàng trong MySQL?