如果公寓只有一个预订,则以下查询有效。但是如果一间公寓预订不止一次,即使没有在请求的时间范围内可用,也会出现此公寓。
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);
考虑以下。
DROP TABLE IF EXISTS apartment; CREATE TABLE apartment (apartment_id SERIAL PRIMARY KEY ,apartment_name varchar(255) NOT NULL ); INSERT INTO apartment VALUES (1, 'Apartment 1'), (2, 'Apartment 2'), (3, 'Apartment 3'), (4, 'Apartment 4'); DROP TABLE IF EXISTS booking; CREATE TABLE booking (booking_id SERIAL PRIMARY KEY ,start_date DATE NOT NULL ,end_date DATE NOT NULL ,apartment_id INT NOT NULL ); INSERT INTO booking 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); SELECT a.* FROM apartment a LEFT JOIN booking b ON b.apartment_id = a.apartment_id AND b.start_date <= '2018-07-23' AND b.end_date > '2018-07-21' WHERE b.booking_id IS NULL; +--------------+----------------+ | apartment_id | apartment_name | +--------------+----------------+ | 2 | Apartment 2 | | 3 | Apartment 3 | | 4 | Apartment 4 | +--------------+----------------+
实际上,除非绑定在事务中,否则像这样的SELECT毫无意义,因为在您仍在检查可用性时,另一个用户可以轻松地进行预订。