鉴于此架构:
Hotel(hotelNo, hotelName, city) #hotelNo is PK
Room (roomNo, hotelNo, type, price) #(roomNo, hotelNo) is PK
Booking (hotelNo, guestNo, dateFrom, dateTo, roomNo) #(hotelNo,guestNo, dateFrom) is PK
Guest(guestNo, GuestName, GuestAddress) #guestNo is PK
问: 今天每间酒店空置房间的收入损失是多少?
在解决方案时,我得到了一个非常不同的答案(更复杂,但基本上我找到all rooms in hotels
并计算Difference
设置运算符对all rooms which are booked today
然后计算出的价格剩下的房间有一个分组条款 - 我甚至不确定它会起作用,但在纸面上看起来有效。但是,看一下示例解决方案:
SELECT hotelNo, SUM(price) FROM Room r
WHERE roomNo NOT IN
(SELECT roomNo FROM Booking b, Hotel h
WHERE (dateFrom <= CURRENT_DATE AND
dateTo >= CURRENT_DATE) AND
b.hotelNo = h.hotelNo)
GROUP BY hotelNo;
为什么我们需要加入预订和酒店。我看到我们加入了基于b.hotelNo=h.hotelNo
的两个关系,但是看一下架构,预订提供了关于RoomNo(已预订)的详细信息,并提供了有关哪个酒店和日期的信息......当然这就是我们的所有信息需要使用Group By子句来实现我们想要的结果吗?还是我弄错了?
答案 0 :(得分:1)
您不需要hotel
表。 booking
中的外键值适用于比较,假设所有预订确实适用于酒店。
这应该可以正常工作,即使需要HotelNo
和RoomNo
来识别预订和房间:
SELECT hotelNo, SUM(price)
FROM Room r
WHERE r.roomNo NOT IN (SELECT b.roomNo
FROM Booking b
WHERE (dateFrom <= CURRENT_DATE AND dateTo >= CURRENT_DATE) AND
b.hotelNo = r.hotelNo
)
GROUP BY hotelNo;
然而,拆分像这样的配对关系是很尴尬的。请改用not exists
:
SELECT hotelNo, SUM(price)
FROM Room r
WHERE NOT EXISTS (SELECT 1
FROM Booking b
WHERE (dateFrom <= CURRENT_DATE AND dateTo >= CURRENT_DATE) AND
b.hotelNo = r.hotelNo and
b.roomNo = r.roomNo
)
GROUP BY hotelNo;
当然,您可以将其写为join
,但即使使用join
,也不需要hotel
表:
SELECT r.hotelNo, SUM(r.price)
FROM Room r left join
Booking b
ON b.dateFrom <= CURRENT_DATE AND
b.dateTo >= CURRENT_DATE and
b.roomNo = r.roomNo and b.hotelNo = r.hotelNo
WHERE b.roomNo is null
GROUP BY r.hotelNo;
答案 1 :(得分:0)
如果我理解正确,这就是我要写的查询类型:
SELECT hotelNo, SUM(price) FROM Room r
left join
(SELECT roomNo , hotelNo
FROM Booking b
join Hotel h ON b.hotelNo = h.hotelNo
WHERE dateFrom <= CURRENT_DATE AND
dateTo >= CURRENT_DATE) a
ON a. roomNo = r.roomNo and a.hotelNo= r.hotelNo
WHERE a.roomNo is null
GROUP BY hotelNo;