具有复杂条件的SQL选择

时间:2018-09-12 08:07:19

标签: mysql sql

我正在用一些SQL查询以及它背后的逻辑做事。

假设我们有这些表:

餐桌酒店

+----+---------+
| id | name    |
+----+---------+
| 1  | Hotel A |
+----+---------+

表hotel_rooms

+----+----------+-----------+
| id | hotel_id | room_type |
+----+----------+-----------+
| 1  | 1        | dbl       | <- can be used as A,B,C,D,E,F
| 2  | 1        | dbl       | <- can be used as B,C,D,E,F
| 3  | 1        | sng       | <- can be used as A
| 4  | 1        | trp       | <- can be used as D,E,F
+----+----------+-----------+

表hotel_room_usages

+----+---------+-------+
| id | room_id | usage |
+----+---------+-------+
| 1  | 1       | B     |
| 2  | 1       | C     |
| 3  | 1       | A     |
| 4  | 1       | D     |
| 5  | 1       | E     |
| 6  | 1       | F     |
| 7  | 2       | B     |
| 8  | 2       | C     |
| 9  | 2       | D     |
| 10 | 2       | E     |
| 11 | 2       | F     |
| 12 | 3       | A     |
| 13 | 4       | D     |
| 14 | 4       | E     |
| 15 | 4       | F     |
+----+---------+-------+

如果我搜索2个使用A的房间 3个使用D的房间作为单独的查询,结果应该是带有相应房间ID的Hotel A。

问题是,如果我同时搜索2个使用情况A 的房间和 3个使用情况D的房间,则它还会返回酒店A,因为它不计算某些房间的可使用性分别是A和D。
房间应该是唯一的,总共是5 /。当前示例不应返回结果,因为酒店总共有4个房间。

2 个答案:

答案 0 :(得分:1)

这有帮助吗?

-两个房间使用情况

select id from hotel_room_usages where usage = 'a'

-用法为d的三个房间

select id from hotel_room_usages where usage = 'd'

-拥有两个房间的房间数量

select count(distinct(room_id)) from hotel_room_usages where usage in ('a','d')

答案 1 :(得分:0)

SELECT h.name AS hotel_name
, q.*
FROM
(
  SELECT r.hotel_id
  , COUNT(DISTINCT CASE WHEN ruA.room_id IS NOT NULL AND ruD.room_id IS NULL THEN ruA.room_id END) AS TotalRoomsOnlyA
  , COUNT(DISTINCT CASE WHEN ruD.room_id IS NOT NULL AND ruA.room_id IS NULL THEN ruD.room_id END) AS TotalRoomsOnlyD
  , COUNT(DISTINCT CASE WHEN ruA.room_id IS NOT NULL AND ruD.room_id IS NOT NULL THEN r.id END) AS TotalRoomsAandD
  , COUNT(DISTINCT r.id) AS TotalRoomsAorD
  FROM hotel_rooms AS r
  LEFT JOIN hotel_room_usages AS ruA ON (ruA.room_id = r.id AND ruA.usage = 'A')
  LEFT JOIN hotel_room_usages AS ruD ON (ruD.room_id = r.id AND ruD.usage = 'D')
  WHERE (ruA.room_id IS NOT NULL OR ruD.room_id IS NOT NULL)
  GROUP BY r.hotel_id
) q
JOIN hotels AS h ON (h.id = q.hotel_id)
CROSS JOIN (SELECT 2 AS a, 3 AS d) AS n
WHERE TotalRoomsAorD >= (a+d)
  AND (
        ((TotalRoomsOnlyA + TotalRoomsAandD) >= a AND TotalRoomsOnlyD >= d) OR
        (TotalRoomsOnlyA >= d AND (TotalRoomsOnlyD + TotalRoomsAandD) >= d) OR
        ((TotalRoomsOnlyA + TotalRoomsAandD/2) >= a AND (TotalRoomsOnlyD + TotalRoomsAandD/2) >= d)
      )
ORDER BY h.name;

db <>小提琴here

上进行测试