So I have 3 tables in a database
One is hotel which has hotel_id and status
one is partner which has partner_id and partner_name
and one is partner_hotel which has hotel_id and partner_id
What I am trying to get is the count for each partner that has a hotel with the status = 1
The closest I have gotten is
select p.partner_name,count(hotel_id)
from partner_hotel ph
join partner p on p.partner_id = ph.partner_id
group by ph.partner_id;
The problem is that does not limit to ones with a status of 1 and nothing I seem to be doing seems to work.
you should join hotel too if th hotel contain status and group by p.partner_id
select p.partner_name,count(*)
from partner_hotel ph
inner join partner p on p.partner_id = ph.partner_id
inner join hotel h on ph.hotel_id = h.hotel_id
where h.status = 1
group by p.partner_id;
or ig hotel use id
select p.partner_name,count(*)
from partner_hotel ph
inner join partner p on p.partner_id = ph.partner_id
inner join hotel h on ph.hotel_id = h.id
where h.status = 1
group by p.partner_id;
I guess you're trying to find the number of partners with one or more hotels having a status = 1. If my guess is correct, this gets you the one number.
SELECT COUNT(DISTINCT p.partner_id) partner_count
FROM partner p
JOIN partner_hotel ph ON p.partner_id = ph.partner_id
JOIN hotel h ON ph.hotel_id = h.hotel_id AND h.status = 1
If your requirement is to show one result row for each partner showing the number of hotels with status = 1, that will go like this.
SELECT COUNT(*) hotel_count,
p.partner_id
FROM partner p
JOIN partner_hotel ph ON p.partner_id = ph.partner_id
JOIN hotel h ON ph.hotel_id = h.hotel_id AND h.status = 1
GROUP BY p.partner_id
Pro tip: When preparing to write a query, it's helpful to imagine the result set you want. Ask yourself these questions:
How many rows must the result set have?
It should have one row per ____ (row per what? Hotel, Partner, Guest, Hotel with status = 1?).
Each row should show ____ values?
If you do this work of imagination, writing the query will be much easier.
Related
Right now i have these two tables
doctor_id and their appointment count
and doctor name and his/her department name
I need to count every department appointments any idea how to connect these two tables ?
Just join all the tables and change the grouping.
SELECT d.name AS department, COUNT(r.d_id) AS appointment_count
FROM departments AS d
JOIN userdelprel AS ud ON d.dept_id = ud.dept_id
JOIN users AS u ON u.u_id = ud.u_id
LEFT JOIN roomreservations AS r ON r.d_id = u.u_id
WHERE u.role_id = 2
GROUP BY d.dept_id
Here is my Airport Table:
id code airport
1 MAA Chennai Airport
2 DEL Delhi Airport
Here is my Equipment Table:
id type Desc
1 Q400 Q Series
2 B737 B Series
And Here is my Schedule Table:
id station equipment
1 1 2
2 2 1
Here is my expected result:
id station equipment
1 MAA B737
2 DEL Q400
How can I do this ?
This is what I have tried so far:
select schedule.id, schedule.station, flight_schedules.equipment
inner join airport where schedule.station = airport.code
How can I get the expected result.
You can use INNER JOIN or LEFT JOIN according to your requirements as indicated on the diagram below. On the other hand, you can follow this approach in order to join multiple tables:
SELECT * FROM
A INNER JOIN
B INNER JOIN
C INNER JOIN
D INNER JOIN
E INNER JOIN F
ON F.eid = E.id
ON E.did = D.id
ON D.cid = C.id
ON C.bid = B.id
ON B.aid = A.id
Here is the diagram for understanding JOIN types in MSSQL below:
You can do:
SELECT s.id, a.code AS station, e.type AS equipment FROM Schedule s
LEFT JOIN Airport a ON a.id = s.station
LEFT JOIN Equipment e ON e.id = s.equipment
i dont know which language do you use but i brought this example which uses sql language and may be it works for some other languages or all of them:-
SELECT Schedule.id, Airport.code, Equipment.type
FROM ((Schedule
INNER JOIN Airport ON Schedule.station = Airport.id)
INNER JOIN Shippers ON Schedule.equipment = Equipment.id);
*Hallo there,
here is the right answer, what you want to have.
But your expacted result is wrong, because you put equipmnet id 2 in table schedule. That why the answer look different by me *
The right code
SELECT Sch.[equipment]
,Air.code
,Equ.type
FROM [Test].[dbo].[Scheule] as Sch
INNER JOIN [Test].[dbo].[Airport] as Air
ON Air.id = Sch.station
INNER JOIN [Test].[dbo].[Equipment] as Equ
ON Equ.id = Sch.id
enter image description here
I have three tables:
Houses Table
id title description
--------------------------
1 Big House Very big house
2 Small House Very small house
Rooms Table
id title room_status
--------------------------
1 Green room 24
2 Yellow room 25
3 Blue room 24
Houses_Rooms Table
id house_id room_id
-------------------------
1 1 1
2 2 3
3 1 2
I have room status 24, for example.
I need get all houses from Houses Table that contains rooms with room_status = 24. But, if house has rooms with different room_status we do not need to choose this house.
I build some query and i use WHERE house.id IN (SELECT ...). It works, but returns houses with same room_status, because IN.
You seem to want houses where all rooms have status 24.
WHERE house.id IN (SELECT ...) is a good idea. Now you need a subquery that only contains houses with only status-24 rooms.
select *
from houses
where id in
(
select hr.house_id
from houses_rooms hr
join rooms r on r.id = hr.room_id
group by hr.house_id
having min(r.room_status) = 24
and max(r.room_status) = 24
);
However, as it is unlikely that a house has no rooms at all, we can simply exclude houses with non-status-24 rooms instead:
select *
from houses
where id not in
(
select house_id
from houses_rooms
where room_id in (select id from rooms where status <> 24)
);
You should use an INNER JOIN instead of a sub-query for this kind of query.
SELECT
HR.ID
,H.Title
,H.Description
,R.Title
FROM #House_Room HR
INNER JOIN #Houses H on HR.HouseID = h.ID
INNER JOIN #Rooms R on HR.RoomID = r.ID
WHERE R.RoomStatus = 24
Returns:
1 | Big House | Very big house | Green room
2 | Small House | Very small house | Blue room
The below query selects all houses that have rooms with room_status = 24, but excludes houses that also have a room_status <> 24. It can probably be further optimized but my SQL is a little rusty:
select h.*
from houses h
join houses_rooms hr on h.id = hr.house_id
join rooms r on hr.room_id = r.id
where r.room_status = 24
and h.id not in (
select h.id
from houses h
join houses_rooms hr on h.id = hr.house_id
join rooms r on hr.room_id = r.id
where r.room_status <> 24
);
SQLFiddle Example
Try this:
SELECT A.*
FROM Houses A JOIN Houses_Rooms B
ON A.id=B.house_id JOIN (SELECT * FROM Rooms WHERE room_status=24) C
ON C.id=B.room_id;
This should work because it uses JOINS to get those that have a room with room_status = 24 and then uses NOT IN to rule out those that have other room statuses
SELECT * FROM Houses_Rooms hr
JOIN Houses h on hr.house_id = h.id
JOIN Rooms r on hr.room_id = r.id
WHERE r.room_status = 24
AND h.id NOT IN(
SELECT h.house_id FROM Houses_Rooms h
JOIN Rooms r on h.room_id = r.id
WHERE r.room_status <> 24
)
Select houses.title as 'house name'
From houses, rooms,houses_rooms
where houses.id=houses_rooms.house_id
and rooms.id=houses_rooms.room_id
and rooms.room_status=24
try this..am not 100% sure..i usually dont use joins.
I'm trying to join 2 sql queries in one query.
The first one gets the count of rooms per hotel.
The second one gets the count of checked guests in hotel.
I'm trying to get occupancy rate per hotel.
SELECT hotel_id, count(room_id)
FROM room
group by room.hotel_id
SELECT h.hotel_id, count(k.room_id)
FROM room_reservation as kr , room as k , hotel as h
where kr.room_id = k.room_id and k.hotel_id = h.hotel_id
group by k.hotel_id
How can i do this ?
select aux.hotel_id, ((coalesce(aux2.total, 0)*1.0)/aux.total)*100 as 'ocupancy rate'
from (SELECT hotel_id, count(room_id) as 'total'
FROM room
group by room.hotel_id) aux
LEFT OUTER JOIN (SELECT h.hotel_id, COUNT(k.room_id) as 'total'
FROM room_reservation as kr
INNER JOIN room as k ON (kr.room_id = k.room_id)
INNER JOIN hotel as h ON (k.hotel_id = h.hotel_id)
GROUP BY k.hotel_id) aux2 on aux.hotel_id = aux2.hotel_id
You can definitely do this with one query. One approach is just to union together your queries.
However, I think the following does what you want in one stroke:
SELECT r.hotel_id, count(distinct k.room_id) as numrooms,
count(distinct kr.room_id) as numreserved
FROM room k left outer join
room_reservation kr
on kr.room_id = k.room_id
group by r.hotel_id
I'm not positive, without knowing more about the tables. In particular, reservations have a time component which rooms and hotels don't have. How is this incorporated into your queries?
Join all your queries, aggregate to get the number of rooms/reservations per hotel, and divide:
SELECT hotel_id,
COUNT(DISTINCT r.room_id) / CONVERT(decimal, COUNT(*)) * 100.0 AS occupancy_rate
FROM hotel h
LEFT OUTER JOIN room r ON h.hotel_id = r.hotel_id
LEFT OUTER JOIN room_reservation rr ON r.room_id = rr.room_id
GROUP BY h.hotel_id
i hope this is self-explanatory:
select hotel_id, sum(guests)/count(room_id) occupancy_level
from (
select r.hotel_id, r.room_id, count(*) guests
from room r
left join room_reservation rr on rr.room_id = r.room_id
group by r.hotel_id, r.room_id
) temp
group by hotel_id
UPDATE - inspired by #Gordon Linoff to include unreserved rooms:
select r.hotel_id, count(*) / count(distinct r.room_id) occupancy_level
from room r
left join room_reservation rr on rr.room_id = r.room_id
group by r.hotel_id, r.room_id
It can be done very simply assuming that there will always be equal or less reservations than total hotel rooms at any given time in the room_reservation table and that a hotel room will only have 0 or 1 corresponding rows in the room_reservation table as previous reservations for a room are deleted (it seems that way because in your second query, you are not doing any kind of filtration like selecting only the most recent reservations per room, etc.):
SELECT
a.hotel_id,
(COUNT(b.room_id) / COUNT(*))*100 AS occupancy_rate
FROM
room a
LEFT JOIN
room_reservation b ON a.room_id = b.room_id
GROUP BY
a.hotel_id
If you need more details about the hotel beyond just the hotel_id, an additional INNER JOIN will be required.
Facing a problem and not getting the hint for a few hours. Maybe onyone can help me out.
Have the following query which shows the Topsellers. So the status of the product (active or not) is saved in b.Article_Status (0=inactive, 1=active).
How do I get the products of the result list which have no active product in the productfamily at the moment. But the product shall still be shown if an old one was ordered (and so is in table order_items) is now inactive and the active one was not ordered yet.
Actual query looks as follow. Already fund a solution which works when the actual active product has been ordered once, but still the problem with the mentioned case.
SELECT count( a.order_itemid ) AS numOrders, c.Product_ID, c.Product_Name, d.producer_name
FROM order_items a
LEFT OUTER JOIN product_article b ON b.Article_ID = a.order_itemid
LEFT OUTER JOIN product c ON b.Article_Productid = c.Product_ID
LEFT OUTER JOIN producer d ON c.Product_Producer = d.producer_id
GROUP BY c.Product_ID
ORDER BY `numOrders` DESC
Solution was a WHERE EXISTS subquery
SELECT count( a.order_itemid ) AS numOrders, c.Product_ID, c.Product_Name, d.producer_name
FROM order_items a
LEFT OUTER JOIN product_article b ON b.Article_ID = a.order_itemid
LEFT OUTER JOIN product c ON b.Article_Productid = c.Product_ID
LEFT OUTER JOIN producer d ON c.Product_Producer = d.producer_id
WHERE EXISTS (SELECT * FROM product_article x WHERE c.Product_ID = x.Article_Productid AND x.Article_Status = 1)
GROUP BY c.Product_ID
ORDER BY `numOrders` DESC
LIMIT 5