重叠预订sql

wljmcqd8  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(320)

这个问题在这里已经有了答案

重叠预订查询(1个答案)
两年前关门了。
我的sql语句也有类似的问题,比如这里的房间预订查询。
如果一个公寓只有一个预订,下面的查询就可以使用。但是,如果一个公寓有多个预订,那么这个公寓也在结果中,尽管它在请求的时间范围内不可用。

SELECT DISTINCT `apartment`.*
FROM `apartment` `apartment`
LEFT JOIN `booking` `booking` ON `apartment`.`uid` = `booking`.`apartment`
WHERE (
    NOT(
        ( `booking`.`start` <= '2018-07-23')
        AND
        ( `booking`.`end` >= '2018-07-21')
    )
)

有人能帮我写正确的sql吗?
更新:根据马特·雷恩斯的提示,我在预订表中添加了一个带有公寓uid的野外公寓。我非常感谢任何帮助我编写正确sql语句的建议!
更新的演示数据如下:

--
-- Table structure for table `apartment`
--
CREATE TABLE `apartment` (
  `uid` int(11) NOT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `bookings` int(10) UNSIGNED NOT NULL DEFAULT '0'
)
--
-- Data for table `tx_apartments_domain_model_apartment`
--
INSERT INTO `apartment` (`uid`, `title`, `bookings`) VALUES
(1, 'Apartment 1', 2),
(2, 'Apartment 2', 1),
(3, 'Apartment 3', 1),
(4, 'Apartment 4', 1);

--
-- Table structure for table `booking`
--
CREATE TABLE `booking` (
  `uid` int(11) NOT NULL,
  `start` date DEFAULT '0000-00-00',
  `end` date DEFAULT '0000-00-00',
  `apartment` int(10) UNSIGNED NOT NULL DEFAULT '0'
)
--
-- Data for table `booking`
--
INSERT INTO `booking` (`uid`, `start`, `end`, `apartment`) VALUES
(1, '2018-07-18', '2018-07-20', 1),
(2, '2018-07-21', '2018-07-23', 1),
(3, '2018-07-18', '2018-07-20', 2);
laawzig2

laawzig21#

我想您正在寻找一份在上述日期范围内没有任何预订的公寓清单。
相反,您的查询将查找至少有一个预订不在问题日期范围内的公寓。
你所链接的问题的答案应该是可行的,但是你也可以试着把问题颠倒过来,找到在日期范围内有预订的公寓。然后使用 LEFT JOIN 和一个 WHERE booking.uid IS NULL 过滤掉那些结果。

SELECT apartment.*
FROM apartment
LEFT JOIN booking ON apartment.uid = booking.apartment
                  AND booking.start <= '2018-07-23' AND booking.end >= '2018-07-21'
WHERE booking.uid IS NULL

您可能还需要考虑为此添加外键 booking.apartment 现场。至少,它应该与 apartment.uid (此时一个是无符号的int(10),另一个是int(11))。
这个 start 以及 end 预定的日期应该是 NOT NULL ,除非您可以预订没有日期的房间。以及 apartment.bookings 字段现在看起来是多余的。

llycmphe

llycmphe2#

您认为这与连接中的多行有关,这是不正确的。问题在于where子句中的逻辑。你不能用日期来说明你想要什么,所以不可能知道解决方案应该是什么。
我简化为只看预订表。我得到两排你只期待一个。你所需要做的就是找出你真正想要的条件。

mysql> SELECT * FROM booking WHERE NOT(start <= '2018-07-23' AND end >= '2018-07-21');
+-----+------------+------------+-----------+
| uid | start      | end        | apartment |
+-----+------------+------------+-----------+
|   1 | 2018-07-18 | 2018-07-20 |         1 |
|   3 | 2018-07-18 | 2018-07-20 |         2 |
+-----+------------+------------+-----------+
2 rows in set (0.00 sec)

相关问题