MySql запрос, чтобы найти свободные номера, указанные даты "От" и "до" - PullRequest
0 голосов
/ 15 ноября 2018

Таблицы выглядят следующим образом

rooms(RoomId(PK)(int),
      RoomName(varchar))

bookings(RoomId(FK)(int),
         From_D(date),
         To_D(date),
         Bookee(varchar))

(PK-primary Key ,FK-foreign Key)

Учитывая даты arrival(From_D) и departure(To_D), как мне узнать номер доступных номеров

Я пытался:

SELECT DISTINCT RoomId 
FROM bookings 
WHERE  arrival not in(From_D,To_d) AND 
       departure not in(From_D,To_d)

Но при рассмотрении структуры моей БД возникает проблема, если в БД хранится многократное бронирование комнаты, и она бронирует комнату, даже если она не была бесплатной в этом диапазоне дат

Ответы [ 4 ]

0 голосов
/ 15 ноября 2018
select distinct r.*
from rooms r
    left join bookings b on b.RoomId=r.RoomId
where b.RoomId is null or @arrival > To_D or @departure < from_td
0 голосов
/ 15 ноября 2018
Try this :
    SELECT * FROM   rooms room1
    WHERE  NOT EXISTS (SELECT *
                FROM   booking booking1
                       WHERE  room1.roomid = booking1.roomid AND
                              (:from_d BETWEEN booking1.from_d AND booking1.to_d OR
                               :to_d   BETWEEN booking1.from_d AND booking1.to_d))
0 голосов
/ 15 ноября 2018

Рассмотрим следующую диаграмму (извините за плохой почерк):

enter image description here

На приведенной выше диаграмме мы можем видеть диапазоны дат на горизонтальной оси.From_D до To_D представляет собой забронированный слот для определенной комнаты.Четыре случая рассматриваются для дат прилета и отъезда (обозначены A i и D i ).

Мы можем ясно видеть, что конкретная комната доступна * только когда даты прибытия и отъезда полностью либо слева, либо справа от забронированного слота.

Мы можем GROUP BY на RoomID и рассматривать только те комнаты, где каждыйбронирование по следующим критериям, определенным выше, с использованием предложения HAVING.

Запрос будет выглядеть следующим образом:

SELECT RoomID 
FROM bookings 
GROUP BY RoomID 
HAVING 
  SUM((From_D < :arrival AND To_D < :arrival) 
             OR 
      (From_D > :departure AND To_D > :departure)) = COUNT(*)

Демонстрация в БДСкрипка

CREATE TABLE `rooms` (
 `RoomId` int(4) NOT NULL,
 `RoomName` varchar(20) DEFAULT NULL,
 PRIMARY KEY (`RoomId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `bookings` (
 `RoomId` int(4) NOT NULL,
 `From_D` date NOT NULL,
 `To_d` date NOT NULL,
 `B_Name` varchar(20) NOT NULL,
 KEY `RoomId` (`RoomId`),
 CONSTRAINT `bookings_ibfk_1` FOREIGN KEY (`RoomId`) REFERENCES `rooms` (`RoomId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `rooms` (`RoomId`, `RoomName`) VALUES 
('1', 'Auditorium'), 
('2', 'Room2'), 
('3', 'Room3'), 
('4', 'Room4'), 
('5', 'Room5');

INSERT INTO `bookings` (`RoomId`, `From_D`, `To_d`, `B_Name`) VALUES 
('1', '2018-11-01', '2018-11-03', 'Trance'), 
('2', '2018-11-02', '2018-11-07', 'Alcoding'), 
('3', '2018-11-01', '2018-11-04', 'DebSoc'), 
('4', '2018-11-12', '2018-11-17', 'MunSoc'), 
('5', '2018-11-03', '2018-11-06', 'Pulse');

Запрос: Проверить наличие мест в период с 2018-11-01 по 2018-11-03

SELECT RoomId 
FROM bookings 
GROUP BY RoomID 
HAVING 
  SUM((From_D < '2018-11-01' AND To_D < '2018-11-01') 
             OR 
      (From_D > '2018-11-03' AND To_D > '2018-11-03')) = COUNT(*)

Результат: Только RoomId 4 доступен согласно данным выборки

| RoomId |
| ------ |
| 4      |
0 голосов
/ 15 ноября 2018

Используйте МЕЖДУ и И с вашей датой

SELECT DISTINCT RoomId FROM bookings    
WHERE (date_field BETWEEN From_D AND To_d)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...