3

我有一张桌子,里面放着一堆书。客户可以在一天中的任何时间进行预约。我想确保不存在与新预订冲突的预订。

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

这是我正在使用的查询。(状态和活动是我需要的其他一些字段)。我找到相关日期,然后查看上午 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)

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

4

3 回答 3

4

要检查一个范围是否与另一个范围重叠,首先要考虑它何时不重叠,然后再反转条件。很明显:

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

这样您就可以处理所有极端情况,例如一个区间完全包含另一个区间。

于 2013-07-11T12:51:08.663 回答
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 中。相反,您希望(我认为)查看应用程序的开始或结束是否与另一个重合:

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.
于 2013-07-11T12:43:17.600 回答
1

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

数据库中的记录是 starttime 8:30:00 endtime 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')
)
于 2016-10-19T18:12:20.043 回答