Mysql查询,看看预订是否会与另一个预订发生冲突。

时间:2013-07-11 12:37:33

标签: mysql select

我有一张桌子可以存放一堆书。客户可以在白天的任何时间预约。我想确保预订不存在会与新预订冲突。

所以我想在那个日期找到预订,并检查开始和结束时间是否重叠。我尝试使用子选择查询来获取当天的预订,然后查看这些时间是否重叠但它似乎没有起作用。

这是我正在使用的查询。 (状态和活动是我需要的其他一些领域)。我找到了相关的日期,然后看看早上8点是在这些结果之间的个别开始/结束时间还是在上午9点40分之间也是在开始/结束时间之间。

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 个答案:

答案 0 :(得分:4)

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

这意味着新约会(8至9:40)完全位于现有的appt内。相反,你想(我认为)看看appt的开头或结尾是否与另一个重合:

WHERE ('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))
-- if you get a row, then there is a conflicting appt.

答案 1 :(得分:3)

要检查一个范围是否与另一个范围重叠,当它不重叠然后反转条件时,更容易先思考。很明显:

  

如果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'

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

答案 2 :(得分:1)

我遇到了同样的问题而且我使用了发布的解决方案,但是如果前一条记录位于新记录中,则会发现另一个错误

数据库中的记录是 starttime 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')
)