我的sql语句类似这里的问题Room Booking Query。
如果一间公寓只有一个预订,则以下查询有效。但是如果一间公寓有多个预订,那么即使在请求的时间段内无法使用,也会出现此公寓。
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吗?
更新: 根据马特·雷恩斯(Matt Raines)的提示,我在预订表上添加了带有公寓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);
答案 0 :(得分:0)
您偏离轨道认为这与联接中的多行有关。问题在于您在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)
答案 1 :(得分:0)
我认为您正在寻找在相关日期范围内没有任何预订的公寓清单。
相反,您的查询将查找在相关日期范围内至少个预订不的公寓。
the question you have linked to的答案应该可以解决,但您也可以尝试反转问题以查找在该日期范围内有预订的公寓。然后使用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)UNSIGNED,另一个是INT(11))。
除非您可以进行没有日期的预订,否则预订的start
和end
日期可能应该为NOT NULL
。并且apartment.bookings
字段现在看起来很多余。