选择COUNT(复杂查询中的免费客房类别)

时间:2019-06-14 10:11:49

标签: mysql sql subquery

我正在开发酒店房间预订系统。

此系统将包含一定数量的酒店,客房和room_categories。 我已经有了这些东西的桌子。

目前,我需要构建查询以获取给定日期每个房间类别的可用房间数量。

我的房间表是这样的:

--------------------------------------------
| id |  name   | hotel_id |room_category_id|
--------------------------------------------
|  1 | Room #1 |    1     |     1          |
|  2 | Room #2 |    1     |     1          |
|  3 | Room #3 |    1     |     2          |
|  4 | Room #4 |    1     |     2          |
|  5 | Room #5 |    1     |     3          |
|  6 | Room #6 |    1     |     3          |
|  7 | Room #7 |    1     |     4          |
|  8 | Room #8 |    1     |     4          |
--------------------------------------------

房间类别表如下:

----------------------------------
| id |   name   | price | volume |
----------------------------------
|  1 | Standart |  $100 |   2    |
|  2 | Comfort  |  $150 |   2    |
|  3 | Half Lux |  $200 |   3    |
|  4 | Lux      |  $250 |   3    |
----------------------------------

Bookings表是这样的:

------------------------------------------------------------------------
| id | booking_start | booking_end | room_id |room_category_id|hotel_id|
------------------------------------------------------------------------
|  1 |  2019-06-17   | 2019-07-17  |    1    |       1        |    1   |
|  2 |  2019-06-17   | 2019-07-17  |  null   |       2        |    1   |
|  3 |  2019-06-17   | 2019-07-17  |  null   |       3        |    1   |
------------------------------------------------------------------------

我正在尝试查询

SELECT room_categories.name, COUNT(room_categories.name) as quantity FROM rooms

INNER JOIN room_categories
ON rooms.room_category_id = room_categories.id

WHERE hotel_id=1
AND room_categories.id NOT IN  (
Select bookings.room_category_id FROM bookings 
  WHERE '2019-07-28' between booking_start and booking_end 
      OR booking_end between  '2019-06-17'  and  '2019-07-28'  
      OR  '2019-06-17' between booking_start and booking_end 
      OR booking_start between '2019-06-17'  and '2019-07-28'
)

GROUP BY room_categories.name
ORDER BY quantity

让我们想象一下,每个类别有2个房间,每个类别有1个预订。此查询返回个类别,我没有任何预订(在我的情况下为room_category = 4)。

-------------------
|  name  |quantity|
-------------------
|Standart|    2   |
-------------------

我应该如何构建查询以获取正确的计数,如下所示:

|room_category|count|
---------------------
| Standart    |  1  |
| Comfort     |  1  |
| Half Lux    |  1  |
| Lux         |  2  |
---------------------

1 个答案:

答案 0 :(得分:1)

您的问题对于“可用”的含义以及所需的日期有点模糊。让我假设您想要按类别列出在2019年6月17日至2019年7月28日整个期间可用的房间数量(这对我来说似乎很长,而一家拥有该房间的酒店整个时期似乎生意都不好。

SELECT rc.name,
       COUNT(b.room_id IS NULL) as quantity 
FROM rooms r JOIN
     room_categories rc
     ON rc.room_category_id = r.id LEFT JOIN
     bookings b
     ON b.room_id = r.room_id AND
        b.booking_start <= '2019-07-28' AND
        b.booking_end >= '2019-06-17'
WHERE r.hotel_id = 1
GROUP BY rc.name
ORDER BY quantity DESC;

LEFT JOIN与日期范围内有预订的任何预订匹配。然后,外部查询将对不匹配的行进行计数。请注意,WHERE子句中的过滤器为 not ,因此您可以获得0的计数。