简体   繁体   中英

How to find the most common value after joining three tables

I have to write a SQL query that, for every user, will return the name of the room that was the most frequently reserved by the user.

I created one of the three tables:

SELECT   User.Name as user_name, Room.Name as room_reser  
FROM     Reservation 
INNER JOIN User ON User.Id = Reservation.UserId 
INNER JOIN Room ON Room.Id = Reservation.RoomId

Table of 3:

Name          room_rese                             name     common_room
Jack           room_1
Anna           room_2                I need =>      Jack       room_1
Jack           room_1
Anna           room_1                               Anna        room_2
Jack           room_2
Anna           room_2

I tried something like this but I don't know how to use it in this case :

SELECT DISTINCT r.user_name, (
    select b.room_reser
    from Reservation b
    where b.user_name = r.user_name
    group by b.user_name, b.roo_reser
    order by count(*) desc
    limit 1
    ) as roo_reser from Reservation r)`

If you are running a database that supports window functions, you can do this with aggregation and window function rank() :

select user_name, room_name
from (
    select   
        us.name as user_name, 
        ro.name as room_name,
        rank() over(partition by re.userid order by count(*) desc) rn
    from reservation re
    inner join user us on us.id = re.userid 
    inner join room ro on ro.id = re.roomid
    group by re.userid, re.roomid, us.name, ro.name
) t
where rn = 1

The inner query aggregates by user name and room, and ranks rooms per user. The outer query filters on the top room per user. If there are ties (ie the two most reserved room of a user have the same number of reservations), then both will be displayed - if you want a single record even if there are ties, you can add another sorting criteria to break the tie.


If your database does not support window function, you could try and filter in the having clause with an aggregate correlated subquery:

select   
    us.name as user_name, 
    ro.name as room_name
from reservation re
inner join user us on us.id = re.userid 
inner join room ro on ro.id = re.roomid
group by us.name, ro.name
having count(*) = (
    select count(*) 
    from reservation re1 
    where re1.userid = re.userid
    group by re1.roomid
    order by count(*) desc
    limit 1
)
SELECT   DISTINCT User.Name as user_name, Room.Name as room_reser  
FROM     Reservation 
INNER JOIN User ON User.Id = Reservation.UserId 
INNER JOIN Room ON Room.Id = Reservation.RoomId 
GROUP BY user_name, room_reser 
ORDER BY COUNT(room_reser)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM