web-dev-qa-db-ja.com

MySQL-予約範囲外の一部の部屋を表示

ビュー内で選択クエリを使用して、部屋が利用可能になる時期を検索しています。予約は、参照と開始/終了日で識別されます。

見る:

USE CATTERY2;
CREATE VIEW RoomAvalability
AS
SELECT ROOMINFO.ID,# ROOMINFO.`Type`, ROOMINFO.Max,
    #GROUP_CONCAT(DISTINCT BOOKROOM.Ref) as Bookings,
    GROUP_CONCAT(DISTINCT BOOK.Ref) as BookRef, ##
    GROUP_CONCAT(DISTINCT BOOK.Start_Date) as StartDate,
    GROUP_CONCAT(DISTINCT BOOK.End_Date) as EndDate
FROM ROOMINFO
LEFT JOIN BOOKROOM ON ROOMINFO.ID = BOOKROOM.ID
INNER JOIN BOOK ON ROOMINFO.ID AND BOOK.Ref = BOOKROOM.Ref ##
GROUP BY ROOMINFO.ID, ROOMINFO.`Type`, ROOMINFO.Max;

ルームは、ログに記録された現在の予約内で複数の予約(重複しない)を持つことができます。

私が現在抱えている問題は、日付範囲を指定するための選択クエリです。私はそれに取り掛かることができません。

指定した日付範囲の予約がない部屋のリストをクエリから返したいのですが。

私は現在、テストのために次の3つの選択を試みています。

#1
SELECT * FROM RoomAvalability;
#2
SELECT ID, `Type`, Max FROM RoomAvalability WHERE NOT StartDate <= '2019-11-22' AND EndDate <= '2020-11-28';
#3
SELECT ID, `Type`, Max FROM RoomAvalability WHERE StartDate <= '2019-11-22' AND EndDate <= '2020-11-28';

1はすべての部屋を返します

2はすべての部屋も返します

3は部屋を返しません

1と2の結果:

ID, type max
1   2   4
2   2   4
3   2   4
4   1   2
5   1   2
6   1   2
7   1   2
8   1   2
9   1   2
10  1   2

2番は3番のネガティブなので、10室ではなく8室を返す必要はありませんか?

番号3は結果を提供せず、この範囲内に予約がないことを意味しますが、2つの結果を提供する必要がありますか?

私が考えているもう1つのこと:予約から始めて、代わりに部屋をリンクする必要がありますか?

構造と値

CREATE SCHEMA CATTERY2;
USE CATTERY2;
#BOOK
CREATE TABLE BOOK(
           Ref INT NOT NULL AUTO_INCREMENT,                    
           Start_Date DATE NOT NULL,
           End_Date DATE NOT NULL,
           PRIMARY KEY(Ref));
#ROOM
CREATE TABLE ROOMINFO(
          ID INT NOT NULL AUTO_INCREMENT,                       
          `Type` VARCHAR(10) NOT NULL,
          Max TINYINT NOT NULL,
          PRIMARY KEY(ID));
#BOOKROOM
CREATE TABLE BOOKROOM(
           Ref INT NOT NULL,
           ID INT NOT NULL,
           FOREIGN KEY (Ref) REFERENCES BOOK(Ref),
           FOREIGN KEY (ID) REFERENCES ROOMINFO(ID));

INSERT INTO BOOK(Start_Date, End_Date) VALUES   
("2019-11-22", "2019-11-25"),
("2019-11-24", "2019-11-28"),
("2019-12-01", "2019-12-02"),
("2019-12-01", "2019-12-06"),
("2019-12-02", "2019-12-03"),
("2019-12-04", "2019-12-10"),
("2019-12-04", "2019-12-10"),
("2019-12-05", "2019-12-13"),
("2019-12-16", "2019-12-19"),
("2019-12-26", "2019-12-28"),
("2019-12-26", "2020-01-01"),
("2019-12-28", "2020-01-02"),
("2019-12-31", "2020-01-05"),
("2020-01-03", "2020-01-08"),
("2020-01-05", "2020-01-11"),
("2020-01-06", "2020-01-09"),
("2020-01-06", "2020-01-11"),
("2020-01-08", "2020-01-18"),
("2020-01-11", "2020-01-15"),
("2020-01-15", "2020-01-17"),
("2020-01-15", "2020-01-18");

INSERT INTO ROOMINFO (ID, `Type`,Max) VALUES
(1, "Family", 4),
(2, "Family", 4),
(3, "Family", 4),
(4, "Dual", 2),
(5, "Dual", 2),
(6, "Dual", 2),
(7, "Dual", 2),
(8, "Dual", 2),
(9, "Dual", 2),
(10, "Dual", 2);

INSERT INTO BOOKROOM( Ref, ID ) VALUES
(1, 4),
(2, 3),
(3, 4),
(4, 5),
(5, 6),
(6, 7),
(7, 3),
(8, 2),
(9, 1),
(10, 8),
(11, 3),
(12, 9),
(13, 2),
(14, 10),
(15, 4),
(16, 5),
(17, 6),
(18, 7),
(19, 2),
(20, 1),
(21, 10);

1

これを試して:

SELECT r.id
FROM ROOMINFO AS r
WHERE NOT EXISTS (SELECT 1 
                    FROM BOOKROOM br
                    JOIN BOOK b ON br.ref = b.ref
                    WHERE r.id = br.id
                        AND ('2019-11-22' BETWEEN b.Start_Date AND b.End_Date
                            OR '2019-11-28' BETWEEN b.Start_Date AND b.End_Date
                            OR b.Start_Date BETWEEN '2019-11-22' AND '2019-11-28'
                            OR b.End_Date BETWEEN '2019-11-22' AND '2019-11-28'
                            )
                  );

または、BOOKテーブルにルームIDを追加すると、次のクエリを使用できます。

SELECT r.id
FROM ROOMINFO AS r
WHERE NOT EXISTS (SELECT 1 
                    FROM BOOK 
                    WHERE r.id = id
                        AND ('2019-11-22' BETWEEN Start_Date AND End_Date
                            OR '2019-11-28' BETWEEN Start_Date AND End_Date
                            OR Start_Date BETWEEN '2019-11-22' AND '2019-11-28'
                            OR End_Date BETWEEN '2019-11-22' AND '2019-11-28'
                            )
                );

この場合、サポートインデックスON BOOK(id、Start_Date、End_Date)を作成できます。

0
Nikita