mysql - 从搜索房间是否已预订的 SQL 查询中排除值
问题描述
我正在尝试让酒店预订系统返回未预订且特定房间大小的房间的房间 ID(我将其用作房间号),在本例中为 Single。
这是我目前正在使用的
SELECT *
FROM rooms
WHERE room_id NOT IN(SELECT room_id
FROM room_bookings
WHERE '2021/04/27' BETWEEN check_in_date AND check_out_date OR '2021/04/30' BETWEEN check_in_date AND check_out_date)
AND NOT EXISTS (SELECT * FROM rooms WHERE room_size = 'Double')
返回当前未预订的房间 ID 有效,但我希望它只返回单人房间 ID,不包括双人间。
我需要在此查询中添加什么以使其排除双人房?
CREATE TABLE `rooms` (
'room_id` int(11) NOT NULL,
`room_size` varchar(255) NOT NULL,
`floor_number` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `rooms` (`room_id`, `room_size`, `floor_number`) VALUES
(1, 'UNASSIGNED', 'UNASSIGNED'),
(2, 'Double', 'First'),
(3, 'Single', 'First'),
(4, 'Double', 'First'),
(5, 'Single', 'First'),
(6, 'Double', 'Second'),
(7, 'Single', 'Second'),
(8, 'Double', 'Second'),
(9, 'Single', 'Second'),
(10, 'Double', 'Second');
CREATE TABLE `room_bookings` (
`booking_id` int(11) NOT NULL,
`customer_id` int(11) NOT NULL,
`room_id` int(11) NOT NULL,
`manager_id` int(11) NOT NULL,
`check_in_date` date NOT NULL,
`check_out_date` date NOT NULL,
`booking_date` date NOT NULL,
`room_size` varchar(255) NOT NULL,
`lunch` varchar(255) NOT NULL,
`dinner` varchar(255) NOT NULL,
`price` varchar(255) NOT NULL,
`booking_status` varchar(255) NOT NULL,
`payment_status` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `room_bookings` (`booking_id`, `customer_id`, `room_id`, `manager_id`, `check_in_date`, `check_out_date`, `booking_date`, `room_size`, `lunch`, `dinner`, `price`, `booking_status`, `payment_status`) VALUES
(9, 6, 1, 1, '2021-04-27', '2021-04-30', '2021-04-27', 'Double', '2', '2', '£230', 'Pending', 'test'),
(10, 6, 3, 1, '2021-04-29', '2021-05-04', '2021-04-27', 'Double', '3', '4', '£465', 'Pending', 'test'),
(11, 6, 7, 1, '2021-04-28', '2021-04-30', '2021-04-27', 'Double', '0', '0', '£120', 'Pending', 'test'),
(12, 6, 1, 1, '2021-04-29', '2021-05-04', '2021-04-27', 'Double', '2', '2', '£350', 'Pending', 'No Payment');
解决方案
问题出在这句话上:
AND NOT EXISTS (SELECT * FROM rooms WHERE room_size = 'Double')
NOT EXISTS
如果查询返回 0 个结果,则通过返回“真”来工作。只要您有任何“双人房”的房间,查询就会返回结果并且条件将失败。要使用此方法,您可以链接到子查询中的表,通过将主查询中的“rooms”表别名为“r”,将子查询别名为“d”,来挑选出特定的房间。这将确保不存在别名为“d”的“房间”行,该行与您在主查询中查看为“r”的行 ID 相同,并且大小为“双”。
SELECT *
FROM rooms r
WHERE room_id NOT IN(SELECT room_id
FROM room_bookings
WHERE '2021/04/27' BETWEEN check_in_date AND check_out_date
OR '2021/04/30' BETWEEN check_in_date AND check_out_date)
AND NOT EXISTS (SELECT room_id FROM rooms d
WHERE d.room_size = 'Double'
AND d.room_id = r.room_id)
另一种选择是像预订房间一样使用“in”子句
SELECT *
FROM rooms r
WHERE room_id NOT IN (SELECT room_id
FROM room_bookings
WHERE '2021/04/27' BETWEEN check_in_date AND check_out_date
OR '2021/04/30' BETWEEN check_in_date AND check_out_date)
AND room_id NOT IN (SELECT room_id
FROM rooms
WHERE room_size = 'Double')
但是您已经在主查询中查看“房间”表,并且room_id
似乎是主键,尽管它没有显示出来。如果表中只有一个房间room_id
,则您已经可以访问该房间行中的数据。因此,您可以只过滤room_size
该行的值。只要没有重复的room_id
行,其中一个为“单”,另一个为“双”,这将起作用。在这种情况下,“单”行仍会显示在此处:
SELECT *
FROM rooms r
WHERE room_id NOT IN (SELECT room_id
FROM room_bookings
WHERE '2021/04/27' BETWEEN check_in_date AND check_out_date
OR '2021/04/30' BETWEEN check_in_date AND check_out_date)
AND room_size <> 'Double'
推荐阅读
- javascript - 在 JavaScript 函数中将 CSS 设置为文本
- testing - 赛普拉斯不匹配存根路由
- google-bigquery - BigQuery - 从一个非常大的事件表中获取用户会话
- azure-devops - Azure DevOps 中所有资源的安全设置
- asp.net-identity - 在 asp.net core 3.1 播种中设置用户密码
- amazon-web-services - 试图集中 terraform 状态并对承担角色和政策感到非常困惑
- javascript - 单击链接时不会发生任何操作
- python - 在 Docker 中安装熊猫
- laravel - 在 Laravel 中对大数据进行分页
- javascript - 如何使函数更改数组索引?