MySQL查询以查看预订是否与另一个预订冲突。

4
我有一个存储了许多书籍的表格。顾客可以预约一整天中的任何时间段。我想确保没有已经存在的预约会与新预约冲突。因此,我需要找到该日期上的预约,并检查开始和结束时间是否重叠。我尝试使用子查询来获取当天的预约,然后看看这些时间是否重叠,但似乎不起作用。以下是我正在使用的查询(状态和活动是我需要的其他字段)。我找到相关日期,然后查看8点是否在那些结果的单独开始/结束时间之间或9:40am是否也落在开始/结束时间之间。
SELECT event_date, starttime, endtime, status, active 
FROM (SELECT event_date, starttime, endtime, status, active FROM bookings WHERE event_date='2013-07-21' AND status != 'cancelled' AND active !=0 LIMIT 1) AS q1
WHERE ('8:00:00' BETWEEN q1.starttime AND q1.endtime) AND ('9:40:00' BETWEEN q1.starttime AND q1.endtime)

这是最好的使用方法吗?谢谢。

3个回答

5

为了检查一个范围是否与另一个范围重叠,首先更容易的是想一想它何时不会重叠,然后再反过来考虑。 很明显:

如果A在B结束之后开始,或者A在B开始之前结束,则两个范围(A,B)不重叠。

将其转换为SQL代码,您可以获得以下条件以找到重叠范围:

... WHERE NOT ('8:00:00' > q1.endtime OR '9:40:00' < q1.starttime)

如果你想的话,可以重新表达为:
... WHERE q1.endtime > '8:00:00' AND q1.starttime < '9:40:00'

通过这种方式,您可以处理所有的边界情况,例如一个时间间隔完全包含另一个时间间隔。


4

WHERE ('8:00:00' BETWEEN starttime AND endtime) OR ('9:40:00' BETWEEN starttime AND endtime)

这意味着新的预约时间(8点到9点40分)完全在已有的预约时间内。相反,您想要的是看看该预约时间的开始或结束是否与其他预约时间重合:

WHERE ('8:00:00' BETWEEN starttime AND endtime) OR ('9:40:00' BETWEEN starttime AND endtime)

此外,我相信内部选择是不必要的。我认为这将产生相同的效果:

SELECT TOP 1 event_date, starttime, endtime, status, active
FROM bookings 
WHERE event_date='2013-07-21' 
    AND status != 'cancelled' 
    AND active != 0
    AND (('8:00:00' BETWEEN q1.starttime AND q1.endtime)
        OR ('9:40:00' BETWEEN q1.starttime AND q1.endtime))
-- if you get a row, then there is a conflicting appt.

我尝试了那个,但它仍然没有给我结果,但下面的另一个选项在我的情况下起作用了。感谢您的帮助。 - Kat

1
我遇到了同样的问题,我使用了发布的解决方案,但我发现另一个错误,如果上一条记录与新记录相似,例如:

数据库中的记录是 开始时间 8:30:00 结束时间 9:00:00

在这种情况下,该记录将被添加,因为没有找到匹配的行。

SELECT TOP 1 event_date, starttime, endtime, status, active
FROM bookings 
WHERE event_date='2013-07-21' 
    AND status != 'cancelled' 
    AND active != 0
    AND (('8:00:00' BETWEEN q1.starttime AND q1.endtime)
        OR ('9:40:00' BETWEEN q1.starttime AND q1.endtime))

为了解决这个问题,您需要检查起始时间或结束时间是否位于您的新条目之间,如下所示。
SELECT TOP 1 event_date, starttime, endtime, status, active
FROM bookings 
WHERE event_date='2013-07-21' 
    AND status != 'cancelled' 
    AND active != 0
    AND (('8:00:00' BETWEEN q1.starttime AND q1.endtime)
        OR ('9:40:00' BETWEEN q1.starttime AND q1.endtime)
        OR (q1.starttime BETWEEN '8:00:00' AND '9:40:00')
        OR (q1.endtime BETWEEN 8:00:00' AND '9:40:00')
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接