订阅更新

活动参与者:既不是最多也不是最少

SQL 实战 123 题 · 第 98 题 中等 约 2 分钟读完

LeetCode 1355 · 分组计数、双向排名、排除极值

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

按活动计数,再用 RANK() OVER (ORDER BY cnt) 和 RANK() OVER (ORDER BY cnt DESC) 两个排名,两者都不为 1 的保留。也可以写成 cnt NOT IN (最大值, 最小值)。如果可能有零参与的活动,要先用活动表左关联补上 0。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

朋友表记录每个人参加的活动,活动表是活动清单。找出参与人数既不是最多、也不是最少的活动。

表结构

  • Friends:id(主键)、name、activity
  • Activities:id(主键)、name

思路

按活动计数后,同时做升序和降序两个排名,两个排名都不是 1 的活动就是答案。也可以先求出最大和最小人数,再排除等于它们的活动。题目保证每个活动至少一人参加,所以不需要关联活动表。

参考解法

select activity
    from (
        select activity,
        rank()over(order by cnt) rk1,
        rank()over(order by cnt desc) rk2
        from
        (
            select  activity  ,count(*) cnt
            from  Friends
            group by  activity 
        )t1
    )t2
    where rk1 !=1 and rk2 != 1

易错点

  • 并列最多或并列最少的活动都要排除,用 RANK 而不是 ROW_NUMBER。
  • 如果存在没人参加的活动,它才是真正的「最少」,这时必须以活动表为主表 LEFT JOIN 计数。
刷题进度保存在当前浏览器