簡體   English   中英

在MySQL中檢查日期范圍沖突

[英]Checking for date range conflicts in MySQL

我正在寫一個酒店預訂系統。 經過大量研究(包括堆棧溢出),我編寫了此sql來找出免費房間:

SELECT
*
FROM room
WHERE
    room_id NOT IN (
        SELECT room_id
        FROM bookings
        WHERE
                 checkin <= '$check_in'
            AND checkout >= '$check_out'
    )

但問題是它沒有考慮時間檢查是12:00:00和結帳是11:59:00

同樣,它沒有像日期范圍內那樣提供正確的查詢,也無法正常工作,就像我從15-18預訂一個單人房,房間的編號是501。如果我再次運行查詢17-19,這個房間似乎是免費的,但實際上應該是占據。

任何人都可以建議一個很好且有效的sql來獲取准確的日期,這樣就不會發生預訂系統沖突,因為該系統將在實際中實施,因此錯誤會導致很多問題。

提前致謝

您遇到的問題是您的查詢不夠可靠。 當您解決問題時,您所擁有的是:

如果$check_in$check_out定義的范圍以任何方式與checkincheckout定義的范圍重疊,則將預訂房間。 否則,它是免費的。

這意味着:

  • 如果$check_in > = checkin$check_in <= checkout ,客房已預訂
  • 如果$check_out > = checkin$check_out <= checkout ,客房已預訂
  • 如果$check_in <= checkin$check_out > = checkout ,客房已預訂

因此,您需要在子查詢中代表這兩種情況,以獲得所需的信息。

另外,希望您將使用datetime進行比較,而不僅僅是time ,否則會產生副作用。

編輯:SQL查詢

(請記住,可以說有多種方法可以給貓剝皮。我只是提供一個示例,盡可能地保留您已有的貓。我再次假設checkincheckout$check_in$check_out將全部解析為datetime類型)

SELECT *
FROM room
WHERE room_id NOT IN
(SELECT room_id 
 FROM bookings
 WHERE
   (checkin <= '$check_in' AND checkout >= '$check_in') OR
   (checkin <= '$check_out' AND checkout >= '$check_out') OR
   (checkin >= '$check_in' AND checkout <= '$check_out'))

您的原始邏輯非常接近,您只需要交換'$check_in''$check_out'值即可。 即:

SELECT *
FROM room
WHERE room_id NOT IN
(
    SELECT room_id
    FROM bookings
    WHERE checkin <= '$check_out' AND checkout >= '$check_in'
)

Brian Driscoll的答案側重於構成預訂沖突的方案,因此:

---------------|-----Booked-----|---------------
       |----A1----|
                             |----A2----|
                    |--A3--|
            |----------A4----------|

Case A2 & A3: checkin <= '$check_in' AND checkout >= '$check_in'
Case A1 & A3: checkin <= '$check_out' AND checkout >= '$check_out'
Case A4:      checkin >= '$check_in' AND checkout <= '$check_out'

然而,構成沖突的senarios要簡單得多。 只有兩個:

---------------|-----Booked-----|---------------
  |----B1----|                             
                                  |----B2----|

Case B1: checkin > '$check_out'
Case B2: checkout < '$check_in'

因此,可以使用以下SQL表示預訂和潛在預訂之間沒有沖突的情況:

checkin > '$check_out' OR checkout < '$check_in'

要檢查沖突,我們只需要對此進行否定即可。 因此,使用德摩根定律,求反是:

checkin <= '$check_out' AND checkout >= '$check_in'

...得出上面給出的解決方案。

我認為這可能會讓您朝正確的方向開始...

SELECT R.*
FROM room AS R
     LEFT OUTER JOIN bookings AS B USING (room_id)
WHERE B.room_id IS NULL
      OR (B.checkout < '$check_in'
          AND B.checkin > '$check_out')

這里有一些好主意: http : //forums.digitalpoint.com/showthread.php?t=63746

另外,您要使用哪種列類型來進行簽入和簽出? 您確定要在$ check_in和$ check_out中傳遞正確格式的值嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM