Reputation: 145
I've been given the following tables:
Hotel (hotelNo, hotelName,hotelAddress)
Room (roomNo,hotelNo, type, price)
Guest (guestNo, guestName, guestAddress)
Booking (hotelNo,guestNo,dateFrom, dateTo, roomNo)
The question asks: "What is the percentage of hotels still under construction? List the total number of hotels, number of hotels completed, the number of hotels under construction, and the percentage of hotels under construction."
For the total number of hotels I know I can do this:
SELECT COUNT(Hotel.hotelNo)
FROM HOTEL;
2 hotels are under construction which I know I can check for using:
SELECT COUNT(Hotel.hotelNo)
FROM HOTEL
INNER JOIN ROOM
ON ROOM.hotelNo = Hotel.hotelNo
HAVING COUNT(roomNo) = 0;
And then hotels that are completed:
SELECT COUNT(Hotel.hotelNo)
FROM HOTEL
INNER JOIN ROOM
ON ROOM.hotelNo = Hotel.hotelNo
HAVING COUNT(roomNo) > 0;
I don't know how I would go about putting all of these into one query though. I tried something like this:
SELECT COUNT(Hotel.hotelNo),
(SELECT COUNT(Hotel.hotelNo)
FROM HOTEL
LEFT JOIN ROOM
ON ROOM.hotelNo = Hotel.hotelNo
GROUP BY Room.roomNo
HAVING COUNT(roomNo) = 0) as count
FROM HOTEL;
That requires though that I have a group by statement for Hotel.hotelNo
but when added just gives me a table of 10 1's for COUNT(Hotel.hotelNo)
because there are 10 hotels and then 10 2's because 2 hotels are under construction for all those entries.
I want it to look something like this:
TOTAL COMPLETED CONSTRUCTION PERCENTAGE
---------------------------------------
10 8 2 20
How would I go about this?
Upvotes: 1
Views: 218
Reputation: 12485
I would be surprised if your query to get hotels under construction,
SELECT COUNT(Hotel.hotelNo)
FROM HOTEL
INNER JOIN ROOM
ON ROOM.hotelNo = Hotel.hotelNo
HAVING COUNT(roomNo) = 0;
actually worked. The reason I say this is it looks like a query that ought to be a left join, looking for values of hotelNo
for which there are no corresponding rows in ROOM
.
Here is how you might put the two queries together:
SELECT COUNT(*) AS total
, SUM(DECODE(room_cnt, 0, 0, 1)) AS completed
, SUM(DECODE(room_cnt, 0, 1, 0)) AS construction
, SUM(DECODE(room_cnt, 0, 1, 0))/COUNT(*) AS percentage
FROM (
SELECT h.hotelNo, COUNT(r.roomNo) AS room_cnt
FROM hotel h LEFT JOIN room r
WHERE h.hotelNo = r.hotelNo
GROUP BY h.hotelNo
);
You can use CASE
instead of DECODE()
if you are fond of ANSI SQL.
Upvotes: 0
Reputation: 44601
You can try something like this :
SELECT tmp.*
, (tmp.total-tmp.complete) AS construction
, ((1-tmp.complete/tmp.total)*100) AS percentage
FROM ( SELECT COUNT(DISTINCT h.hotelNo) AS total
, COUNT(DISTINCT r.hotelNo) AS complete
FROM HOTEL h
LEFT JOIN ROOM r ON r.hotelNo = h.hotelNo ) tmp
Upvotes: 1