MySQL不重叠日期范围

时间:2018-08-23 14:40:31

标签: mysql

我看到了很多与此类似的问题,但是它们似乎都是为了突出显示日期范围重叠而设计的,我需要相反的情况。

让我们说我有一张这样的桌子

id| start_date | end_date   | room_id
1 | 15/05/2018 | 30/06/2020 | 1
2 | 01/11/2018 | 31/10/2019 | 2
3 | 01/08/2020 | 31/07/2022 | 1
4 | 01/12/2019 | 30/11/2021 | 2
5 | 01/08/2020 | 31/07/2022 | 3

如您所见,每个房间都有多个预订。我需要能够指定一个开始日期或结束日期,或者同时指定两个日期,然后取回不重叠的内容(即可用的房间)

例如,如果我仅指定开始日期为01/05/2018,那么每个房间都将返回,或者如果我仅指定结束日期为30/07/2020,则每个房间都将返回,因为这些日期都不是在每次预订的开始日期和结束日期之间。即使id 1的预订终止于2020年6月30日,新的预订开始于01/08/2020,该预订仍然可用,因为有人可以在这2个日期之间进行预订。

如果我同时指定了开始日期和结束日期,它将搜索并仅返回两个日期之间没有预订的房间。

我在网上阅读了很多问题,逻辑似乎是

SELECT *
FROM bookings
WHERE $start_date < expiry_date AND $end_date > start_date

我了解,但是如果我在上面用以下日期运行了该查询

SELECT *
FROM bookings
WHERE '2018-10-01' < expiry_date AND '2019-10-01' > start_date

它返回

id| start_date | end_date   | room_id
1 | 15/05/2018 | 30/06/2020 | 1
2 | 01/11/2018 | 31/10/2019 | 2

如何获取它,以便在我经过开始日期,结束日期或两者时都返回可用的房间?

1 个答案:

答案 0 :(得分:2)

根据De Morgan的定律,我们可以对您提供的重叠范围查询取反,如下所示:

SELECT *
FROM bookings
WHERE $start_date >= expiry_date OR $end_date <= start_date;

表达式~(P ^ Q)~P V ~Q等效。