繁体   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