题目描述

(通过次数6,351 | 提交次数9,508,通过率66.80%)

表: Friends
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
| activity | varchar |
+---------------+---------+
id 是朋友的 id 和该表的主键
name 是朋友的名字
activity 是朋友参加的活动的名字
表: Activities
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id 是该表的主键
name 是活动的名字
写一条 SQL 查询那些既没有最多,也没有最少参与者的活动的名字
Activities 表中的任意活动都有在Friends 中参与过
可以以 任何顺序 返回结果。
下面是查询结果格式的例子。
示例 1:
输入:
Friends 表:
+------+--------------+---------------+
| id | name | activity |
+------+--------------+---------------+
| 1 | Jonathan D. | Eating |
| 2 | Jade W. | Singing |
| 3 | Victor J. | Singing |
| 4 | Elvis Q. | Eating |
| 5 | Daniel A. | Eating |
| 6 | Bob B. | Horse Riding |
+------+--------------+---------------+
Activities 表:
+------+--------------+
| id | name |
+------+--------------+
| 1 | Eating |
| 2 | Singing |
| 3 | Horse Riding |
+------+--------------+
输出:
+--------------+
| activity |
+--------------+
| Singing |
+--------------+
解释:
Eating 活动有三个人参加, 是最多人参加的活动 (Jonathan D. , Elvis Q. and Daniel A.)
Horse Riding 活动有一个人参加, 是最少人参加的活动 (Bob B.)
Singing 活动有两个人参加 (Victor J. and Jade W.)
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/activity-participants
表: Friends +---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | name | varchar | | activity | varchar | +---------------+---------+ id 是朋友的 id 和该表的主键 name 是朋友的名字 activity 是朋友参加的活动的名字 表: Activities +---------------+---------+ | Column Name | Type | +---------------+---------+ | id | int | | name | varchar | +---------------+---------+ id 是该表的主键 name 是活动的名字 写一条 SQL 查询那些既没有最多,也没有最少参与者的活动的名字 Activities 表中的任意活动都有在Friends 中参与过 可以以 任何顺序 返回结果。 下面是查询结果格式的例子。 示例 1: 输入: Friends 表: +------+--------------+---------------+ | id | name | activity | +------+--------------+---------------+ | 1 | Jonathan D. | Eating | | 2 | Jade W. | Singing | | 3 | Victor J. | Singing | | 4 | Elvis Q. | Eating | | 5 | Daniel A. | Eating | | 6 | Bob B. | Horse Riding | +------+--------------+---------------+ Activities 表: +------+--------------+ | id | name | +------+--------------+ | 1 | Eating | | 2 | Singing | | 3 | Horse Riding | +------+--------------+ 输出: +--------------+ | activity | +--------------+ | Singing | +--------------+ 解释: Eating 活动有三个人参加, 是最多人参加的活动 (Jonathan D. , Elvis Q. and Daniel A.) Horse Riding 活动有一个人参加, 是最少人参加的活动 (Bob B.) Singing 活动有两个人参加 (Victor J. and Jade W.) 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/activity-participants
表: Friends
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| name          | varchar |
| activity      | varchar |
+---------------+---------+
id 是朋友的 id 和该表的主键
name 是朋友的名字
activity 是朋友参加的活动的名字

表: Activities
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| name          | varchar |
+---------------+---------+
id 是该表的主键
name 是活动的名字

写一条 SQL 查询那些既没有最多,也没有最少参与者的活动的名字
Activities 表中的任意活动都有在Friends 中参与过
可以以 任何顺序 返回结果。

下面是查询结果格式的例子。
示例 1:
输入:
Friends 表:
+------+--------------+---------------+
| id   | name         | activity      |
+------+--------------+---------------+
| 1    | Jonathan D.  | Eating        |
| 2    | Jade W.      | Singing       |
| 3    | Victor J.    | Singing       |
| 4    | Elvis Q.     | Eating        |
| 5    | Daniel A.    | Eating        |
| 6    | Bob B.       | Horse Riding  |
+------+--------------+---------------+
Activities 表:
+------+--------------+
| id   | name         |
+------+--------------+
| 1    | Eating       |
| 2    | Singing      |
| 3    | Horse Riding |
+------+--------------+
输出:
+--------------+
| activity     |
+--------------+
| Singing      |
+--------------+
解释:
Eating 活动有三个人参加, 是最多人参加的活动 (Jonathan D. , Elvis Q. and Daniel A.)
Horse Riding 活动有一个人参加, 是最少人参加的活动 (Bob B.)
Singing 活动有两个人参加 (Victor J. and Jade W.)

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/activity-participants
//测试数据
Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30));
Create table If Not Exists Activities (id int, name varchar(30));
insert into Friends (id, name, activity) values ('1', 'Jonathan D.', 'Eating');
insert into Friends (id, name, activity) values ('2', 'Jade W.', 'Singing');
insert into Friends (id, name, activity) values ('3', 'Victor J.', 'Singing');
insert into Friends (id, name, activity) values ('4', 'Elvis Q.', 'Eating');
insert into Friends (id, name, activity) values ('5', 'Daniel A.', 'Eating');
insert into Friends (id, name, activity) values ('6', 'Bob B.', 'Horse Riding');
insert into Activities (id, name) values ('1', 'Eating');
insert into Activities (id, name) values ('2', 'Singing');
insert into Activities (id, name) values ('3', 'Horse Riding');
//测试数据 Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30)); Create table If Not Exists Activities (id int, name varchar(30)); insert into Friends (id, name, activity) values ('1', 'Jonathan D.', 'Eating'); insert into Friends (id, name, activity) values ('2', 'Jade W.', 'Singing'); insert into Friends (id, name, activity) values ('3', 'Victor J.', 'Singing'); insert into Friends (id, name, activity) values ('4', 'Elvis Q.', 'Eating'); insert into Friends (id, name, activity) values ('5', 'Daniel A.', 'Eating'); insert into Friends (id, name, activity) values ('6', 'Bob B.', 'Horse Riding'); insert into Activities (id, name) values ('1', 'Eating'); insert into Activities (id, name) values ('2', 'Singing'); insert into Activities (id, name) values ('3', 'Horse Riding');
//测试数据
Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30));
Create table If Not Exists Activities (id int, name varchar(30));

insert into Friends (id, name, activity) values ('1', 'Jonathan D.', 'Eating');
insert into Friends (id, name, activity) values ('2', 'Jade W.', 'Singing');
insert into Friends (id, name, activity) values ('3', 'Victor J.', 'Singing');
insert into Friends (id, name, activity) values ('4', 'Elvis Q.', 'Eating');
insert into Friends (id, name, activity) values ('5', 'Daniel A.', 'Eating');
insert into Friends (id, name, activity) values ('6', 'Bob B.', 'Horse Riding');

insert into Activities (id, name) values ('1', 'Eating');
insert into Activities (id, name) values ('2', 'Singing');
insert into Activities (id, name) values ('3', 'Horse Riding');

解题思路

源表Friends中保存了每个人参加的活动数据。
题目要求:查询出既不是最热门(参加人数最多),也不是最冷门(参加人数最少)的活动。
那么,首先,我们需要计算出每个活动的参加人数;使用GROUP BY+COUNT汇总即可。
然后,剔除参加人数最多的活动;
最后,剔除参加人数最少的活动;
参加人数最多和最少的活动,可以使用开窗函数,按参加人数倒序和升序排序,分别获取第一名和最后一名。
因为可能会存在并列第一或并列最后一名的情况,所以在使用开窗函数排序时,不适合使用ROW_NUMBER开窗函数。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
activity
from (
select
activity,
rank() over(order by count(1)) rn1,
rank() over(order by count(1) desc) rn2
from Friends
group by activity
)a
where rn1 <> 1
and rn2 <> 1;
select activity from ( select activity, rank() over(order by count(1)) rn1, rank() over(order by count(1) desc) rn2 from Friends group by activity )a where rn1 <> 1 and rn2 <> 1;
select
    activity
from (
    select
        activity,
        rank() over(order by count(1)) rn1,
        rank() over(order by count(1) desc) rn2
    from Friends
    group by activity
)a
where rn1 <> 1
  and rn2 <> 1;
  
picture loss