检查MySQL中的日期范围冲突

Sam*_*nti 7 php mysql

我正在写一个酒店预订系统.经过大量的学习(包括堆栈溢出),我写了这个sql来找出免费房间:

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

但问题是它不考虑时间检查是12:00:00,结账时间是11:59:00

它还没有提供正确的查询,如在日期范围内它不起作用,如果我从15-18预订单个房间的号码是501.如果我再次运行查询17-19这个房间似乎是免费的但实际上它应该是占据.

任何人都可以建议一个非常好的和有效的SQL,它将获得准确的日期,以便预订系统不会发生冲突,因为系统将实际实施,所以错误将导致许多问题.

提前致谢

Bri*_*oll 24

您遇到的问题是您的查询不够健壮.当您解决问题时,您拥有的是:

如果范围由以及以任何方式定义的范围定义$check_in$check_out重叠,则预订房间.否则,它是免费的.checkincheckout

这意味着:

  • 如果$check_in> = checkin$check_in<= checkout,房间BOOKED
  • OR如果$check_out> = checkin$check_out<= checkout,房间BOOKED
  • OR如果$check_in<= checkin$check_out> = checkout,房间BOOKED

因此,您需要在子查询中表示这两种方案,以获取您正在查找的信息.

此外,您希望datetime用于比较而不仅仅是time,否则您将有副作用.

编辑:SQL查询

(请记住,有对皮肤一只猫,可以这么说.我只是提供与你已经拥有尽可能保持一个例子不止一种方法.再次,我还假设checkin,checkout,$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'))
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的抓住!该查询检查范围的两端,但中间怎么样?换句话说,假设客户试图预订一个房间4晚,但它已经在中间预订了一晚?预订签入将大于请求的$ check_in,预订结账将少于请求的$ check_out,但房间不可用....对吗? (3认同)

Pry*_*ryo 10

你的原始逻辑非常接近,你只需要交换'$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'
)
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

但是构成senarios 没有冲突要简单得多.只有两个:

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

Case B1: checkin > '$check_out'
Case B2: checkout < '$check_in'
Run Code Online (Sandbox Code Playgroud)

因此,使用此SQL可以表示预订和潜在预订之间没有冲突的情况:

checkin > '$check_out' OR checkout < '$check_in'
Run Code Online (Sandbox Code Playgroud)

要检查冲突,我们只需要否定这一点.因此,使用DeMorgans法则,否定是:

checkin <= '$check_out' AND checkout >= '$check_in'
Run Code Online (Sandbox Code Playgroud)

...到达上面给出的解决方案.