【问题标题】:How to find the most common value after joining three tables三张表连接后如何找到最常见的值
【发布时间】:2020-02-13 14:35:29
【问题描述】:

我必须为每个用户编写一个 SQL 查询,该查询将返回该用户最常预订的房间的名称。

我创建了三个表之一:

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

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

我尝试过这样的事情,但我不知道在这种情况下如何使用它:

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)`

【问题讨论】:

  • 如果出现平局,预期的结果是什么? (如果用户有两个不同的房间且最大预订数相同。)
  • 好问题,在这个任务中什么都没有,我想它应该为一个用户显示'n'答案。

标签: mysql sql sqlite


【解决方案1】:

如果您运行的数据库支持窗口函数,则可以使用聚合和窗口函数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

内部查询按用户名和房间聚合,并对每个用户的房间进行排名。外部查询过滤每个用户的顶部房间。如果有平局(即用户预订最多的两个房间的预订数量相同),则两者都会显示 - 如果即使有平局也想要一条记录,您可以添加另一个排序条件来打破平局.


如果您的数据库不支持窗口函数,您可以尝试在 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
)

【讨论】:

  • 如果我想使用 SQLite 怎么办?
  • @piotr_python:只要您的版本支持窗口函数,这也应该适用于 sqlite。
  • @GMB 可惜我的 sqlitesupport 不支持窗口功能,没有它有什么办法解决吗?
  • @piotr_python:我用没有窗口函数的 qery 更新了我的答案。
  • 非常感谢,你能解释一下吃完之后会发生什么吗?
【解决方案2】:
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)

【讨论】:

  • DISTINCT 不是函数,它是SELECT DISTINCT 的一部分!跳过那些多余的括号,直接写SELECT DISTINCT User.Name as user_name, Room.Name as room_reser ... 让代码更清晰。
  • 这里不需要SELECT DISTINCT,因为GROUP BY不返回重复项。
猜你喜欢
  • 2023-04-03
  • 2021-09-22
  • 2017-03-28
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 2012-08-31
  • 1970-01-01
相关资源
最近更新 更多