首页 > 解决方案 > 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 的开始日期,那么每个房间都会返回,或者如果我只指定结束日期 2020 年 7 月 30 日,那么每个房间都会返回,因为这两个日期都不在开始日期之间以及每次预订的结束日期。即使 id 1 的预订结束于 2020 年 6 月 30 日,而新的预订于 2020 年 1 月 8 日开始,它仍然可用,因为有人可以在这两个日期之间进行预订。

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

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

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

我如何获得它,以便当我通过开始日期、结束日期或两者时返回可用的房间?

标签: mysql

解决方案


根据德摩根定律,我们可以否定您给出的重叠范围查询,如下所示:

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

表达式~(P ^ Q)等价于~P V ~Q


推荐阅读