SQL - 查询每个酒店有不同成人/儿童的多个房间

时间:2014-04-21 17:42:48

标签: mysql sql database search

我有一个简单的查询,我为每个酒店选择与x成人+ x儿童的可用x房间匹配日期范围,但我很难找到如何查询每个酒店的房间列表如下:

  • 1间带2名成人/ 0名儿童的房间
  • 1间带4名成人/ 2名儿童的房间
  • 1间带2名成人/ 1名儿童的房间

这是我的问题:

SELECT COUNT(pl.day) AS Days,
       p.property_ID AS Hotel_ID,
       p.name AS Hotel_Name,
       r.room_name AS Room_Name,
       r.room_type_ID AS Room_ID
FROM property p
INNER JOIN room_type r ON p.property_ID=r.property_ID
AND (r.max_adults >= 3
     AND r.max_children >= 0)
INNER JOIN plan pl ON pl.room_type_ID=r.room_type_ID
AND (pl.day >= "2014-07-07"
     AND pl.day <= "2014-07-11")
GROUP BY Room_ID,
         Hotel_ID HAVING Days = 4

修改

如何在'No_of_Room'中添加SELECT,以room_types区分房间号,单个房间的示例结果:

Array
(
    [Room_Price] => 160.00
    [Days] => 4
    [Hotel_ID] => 1
    [Hotel_Name] => Hotel Alfa
    [Room_Name] => Room type C
    [Room_ID] => 3
    [Max_Adults] => 3
    [Max_Children] => 1
    [No_of_Room] => 1 // What number of room does this room_type belongs to
)

然后我可以显示结果:

enter image description here

修改

客房表

Rooms(
 ID,
 hotel_id
 room_name,
 max_Adults,
 max_Children
);

-- Populate
INSERT INTO Rooms VALUES (1,1,"Room A",2,1),(2,1,"Room B",2,5),(3,1,"Room C",3,0);
INSERT INTO Rooms VALUES (1,2,"Room A",2,1),(2,2,"Room B",2,5),(3,3,"Room C",3,4);

2 个答案:

答案 0 :(得分:4)

使用VIEW S做事的例子。

对于这个项目,作者可能有别名,例如一本书可能有&#34; S.郎&#34;作为作者,另一个可能有&#34; Serge Lang&#34;,主要作者是主要形式(Serge Lang),次要作品是&#34; S。郎&#34;

将这些联系起来很重要,理想情况下我喜欢和#34; AuthorId&#34;和&#34; PrimaryAuthorId&#34;作为列,这样我就可以在AuthorId上从它选择PrimaryAuthorId等于某事。

为此,视图定义为:

select
  `BookSystem_AuthorList`.`AuthorId` AS `AuthorId`,
  if((`BookSystem_AuthorList`.`duplicateOf` = 0),
    `BookSystem_AuthorList`.`AuthorId`,
    `BookSystem_AuthorList`.`duplicateOf`
  ) AS `PrimaryAuthorId`
from `BookSystem_AuthorList`;

然后

SELECT PrimaryAuthorId FROM BookSystem_PrimaryAuthorId WHERE AuthorId=10;

给出:

7

加入会更好!

然后我使用这个视图来定义另一个视图(EditionAuthorsWithPrimaryId) - 它获取版本的作者 - 以及主要作者(然后我可以根据需要加入以获取名称)

select
  `BookSystem_EditionAuthors`.`BindingId` AS `BindingId`,
  `BookSystem_EditionAuthors`.`EditionId` AS `EditionId`,
  `BookSystem_EditionAuthors`.`AuthorId` AS `AuthorId`,
  `BookSystem_EditionAuthors`.`Position` AS `Position`,
  (select
    `BookSystem_PrimaryAuthorId`.`PrimaryAuthorId`
  from `BookSystem_PrimaryAuthorId`
  where (`BookSystem_PrimaryAuthorId`.`AuthorId` = `BookSystem_EditionAuthors`.`AuthorId`)
  ) AS `PrimaryAuthorId`
from `BookSystem_EditionAuthors`;

现在我能做到:

SELECT * FROM BookSystem_EditionAuthorsWithPrimary WHERE EditionId=10;

BindingId, EditionId, AuthorId, Position, PrimaryAuthorId
10,         10,         10,         0,          7

好多了!

下一个查询是一个很好的例子

select
  `BookSystem_BookList`.`BookId` AS `Id`,
  `BookSystem_BookList`.`Title` AS `Name`,
  `BookSystem_BookList`.`UserId` AS `UserId`,
  `BookSystem_BookList`.`BookType` AS `Subtype`,
  1 AS `IsBook`,0 AS `IsSeries`,
  0 AS `IsAuthor`
from `BookSystem_BookList`

union

select
  `BookSystem_SeriesList`.`SeriesId` AS `Id`,
  `BookSystem_SeriesList`.`SeriesName` AS `Name`,
  `BookSystem_SeriesList`.`UserId` AS `UserId`,
  '' AS `Subtype`,
  0 AS `IsBook`,
  1 AS `IsSeries`,
  0 AS `IsAuthor`
from `BookSystem_SeriesList`

union

select
  `BookSystem_AuthorList`.`AuthorId` AS `Id`,
  concat(
    `BookSystem_AuthorList`.`AuthorSurname`,', ',`BookSystem_AuthorList`.`AuthorForename`,
    ifnull(
      (select concat(
        ' (AKA: ',
        group_concat(
          concat(
            `BookSystem_AuthorList`.`AuthorSurname`,
            ', ',
            `BookSystem_AuthorList`.`AuthorForename`
          ) separator '; '
        ),')'
      ) AS `AKA` from `BookSystem_AuthorList`
        where
          (`BookSystem_AuthorList`.`duplicateOf` = `Id`)
        group by (`BookSystem_AuthorList`.`duplicateOf` = `Id`)
    ),'')) AS `Name`,
    `BookSystem_AuthorList`.`UserId` AS `UserId`,
    '' AS `SubType`,
    0 AS `IsBook`,
    0 AS `IsSeries`,
    1 AS `IsAuthor`
from `BookSystem_AuthorList`
where (`BookSystem_AuthorList`.`duplicateOf` = 0) order by `Name`;

太棒了!

但现在我可以轻松获得UserId = 1的所有内容:

mysql> SELECT * FROM BookSystem_Index WHERE UserId = 1;
+----+----------------------------------------+--------+-------------+--------+----------+----------+
| Id | Name                                   | UserId | Subtype     | IsBook | IsSeries | IsAuthor |
+----+----------------------------------------+--------+-------------+--------+----------+----------+
|  4 | A First Course in Calculus             |      1 | Normal      |      1 |        0 |        0 |
|  2 | A First Course in Real Analysis        |      1 | Normal      |      1 |        0 |        0 |
|  2 | Algebra                                |      1 |             |      0 |        1 |        0 |
| 13 | Analysis II assignments                |      1 | Assignments |      1 |        0 |        0 |
| 14 | Author Test                            |      1 | Normal      |      1 |        0 |        0 |
|  8 | b, g                                   |      1 |             |      0 |        0 |        1 |
|  7 | b, g (AKA: t, lll; Teal, lll)          |      1 |             |      0 |        0 |        1 |
|  1 | Calculus of Several Variables          |      1 | Normal      |      1 |        0 |        0 |
|  4 | DuBois, Paul                           |      1 |             |      0 |        0 |        1 |
|  1 | Lang, Serge (AKA: Lang, S. E. R. G. E) |      1 |             |      0 |        0 |        1 |
|  5 | Linear Algebra                         |      1 | Normal      |      1 |        0 |        0 |
|  3 | Morrey, C. B.                          |      1 |             |      0 |        0 |        1 |
|  6 | MySQL                                  |      1 | Normal      |      1 |        0 |        0 |
|  7 | Principles of Mathematical Analysis    |      1 | Normal      |      1 |        0 |        0 |
|  2 | Protter, M. H.                         |      1 |             |      0 |        0 |        1 |
|  5 | Rudin, Walter                          |      1 |             |      0 |        0 |        1 |
| 10 | t                                      |      1 | Normal      |      1 |        0 |        0 |
|  3 | Test                                   |      1 |             |      0 |        1 |        0 |
| 12 | Test 1                                 |      1 | Normal      |      1 |        0 |        0 |
| 11 | Test 4.4.2014                          |      1 | Normal      |      1 |        0 |        0 |
|  8 | Topology and Analysis                  |      1 | Normal      |      1 |        0 |        0 |
|  3 | Undergraduate Algebra                  |      1 | Normal      |      1 |        0 |        0 |
|  1 | Undergraduate Texts in Mathematics     |      1 |             |      0 |        1 |        0 |
|  9 | w                                      |      1 | Normal      |      1 |        0 |        0 |
+----+----------------------------------------+--------+-------------+--------+----------+----------+
24 rows in set (0.00 sec)

优化器正确地看到视图,它不会生成完整视图,它有效地替换了所需的选择。

(取自测试数据库,不是生产,因此奇怪的名称,如&#34; TESTING&#34;)

答案 1 :(得分:2)

首先,房间类型选择需要正确构图。以下连接可能会有效。

修改

已编辑查询以仅返回包含所有三种房型的属性。它也加入了计划表。

SELECT 
    COUNT(pl.day) AS Days,
    p.property_ID AS Hotel_ID, 
    p.name AS Hotel_Name, 
    r.room_name AS Room_Name, 
    r.room_type_ID AS Room_ID,
    r.max_adults as Max_Adults,
    r.max_children as Max_Children
FROM property p
INNER JOIN room_type r
ON p.property_ID=r.property_ID
INNER JOIN plan pl 
ON pl.room_type_ID=r.room_type_ID
AND (pl.day >= '2014-07-07' AND pl.day <= '2014-07-11')
WHERE EXISTS
    (SELECT 1
    FROM room_type r1
    WHERE p.property_ID=r1.property_ID
    AND r1.max_adults = 2 AND r1.max_children = 0)
AND EXISTS
    (SELECT 1
    FROM room_type r2 
    WHERE p2.property_ID=r2.property_ID
    AND r2.max_adults = 4 AND r2.max_children = 2)
AND EXISTS
    (SELECT 1
    FROM room_type r3 
    WHERE P.PROPERTY_ID=R3.PROPERTY_ID
    AND r3.max_adults = 2 AND r3.max_children = 1)
GROUP BY 
    p.property_ID, 
    p.name, 
    r.room_name, 
    r.room_type_ID,
    r.max_adults,
    r.max_children
HAVING 
    COUNT(pl.day) = 4;