Если вы используете базу данных, которая поддерживает оконные функции, вы можете сделать это с помощью агрегации и оконной функции 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
Внутренний запрос агрегирует по имени пользователя и комнате и ранжирует комнаты по пользователь. Внешние запросы фильтруются в верхней комнате на пользователя. Если есть связи (ie две самые зарезервированные комнаты пользователя имеют одинаковое количество резервирований), то будут отображаться обе - если вы хотите одну запись, даже если есть связи, вы можете добавить другой критерий сортировки, чтобы разорвать t ie.
Если ваша база данных не поддерживает оконную функцию, вы можете попробовать фильтровать в предложении having
совокупный коррелированный подзапрос:
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
)