- 学习:知识的初次邂逅
- 复习:知识的温故知新
练习:知识的实践应用
目录
一,原题力扣链接
二,题干
RequestAccepted
表:+----------------+---------+ | Column Name | Type | +----------------+---------+ | requester_id | int | | accepter_id | int | | accept_date | date | +----------------+---------+ (requester_id, accepter_id) 是这张表的主键(具有唯一值的列的组合)。 这张表包含发送好友请求的人的 ID ,接收好友请求的人的 ID ,以及好友请求通过的日期。编写解决方案,找出拥有最多的好友的人和他拥有的好友数目。
生成的测试用例保证拥有最多好友数目的只有 1 个人。
查询结果格式如下例所示。
示例 1:
输入: RequestAccepted 表: +--------------+-------------+-------------+ | requester_id | accepter_id | accept_date | +--------------+-------------+-------------+ | 1 | 2 | 2016/06/03 | | 1 | 3 | 2016/06/08 | | 2 | 3 | 2016/06/08 | | 3 | 4 | 2016/06/09 | +--------------+-------------+-------------+ 输出: +----+-----+ | id | num | +----+-----+ | 3 | 3 | +----+-----+ 解释: 编号为 3 的人是编号为 1 ,2 和 4 的人的好友,所以他总共有 3 个好友,比其他人都多。进阶:在真实世界里,可能会有多个人拥有好友数相同且最多,你能找到所有这些人吗?
三,建表语句
Create table If Not Exists RequestAccepted (requester_id int not null, accepter_id int null, accept_date date null);
Truncate table RequestAccepted;
insert into RequestAccepted (requester_id, accepter_id, accept_date) values ('1', '2', '2016/06/03');
insert into RequestAccepted (requester_id, accepter_id, accept_date) values ('1', '3', '2016/06/08');
insert into RequestAccepted (requester_id, accepter_id, accept_date) values ('2', '3', '2016/06/08');
insert into RequestAccepted (requester_id, accepter_id, accept_date) values ('3', '4', '2016/06/09');
四,分析
题解:
字段:请求者,接收者,接收日期
要求好友id最多的人。
分析:
我有好友,我的好友也有好友,
所以 接收者同时也是请求者。
解体过程
第一步,查询原表,拿到全部字段;
第二步,查询原表,把requester_id 和accepter_id 掉个个头;
第三步 拼接上述2个表 得到
第四步,分组,聚合。 以requester_id分组,以count(accepter_id)聚合
第五步,进阶解法
五,SQL解答
with t1 as (
select requester_id, accepter_id, accept_date from requestaccepted -- 原表数据
union all
select accepter_id,requester_id, accept_date from requestaccepted -- 把2个字段掉个一下
),t2 as (
select requester_id,count(accepter_id) as cnt from t1 group by requester_id -- 拼接了2个表 然后分组求聚合
),t3 as (
select requester_id,cnt,
rank() over (order by cnt desc ) ro -- 单组求TopN 拿到并列第一
from t2
)
select requester_id as id,cnt as num from t3 where t3.ro=1; -- 单组求TopN 拿到并列第一
六,验证
七,知识点总结
- 既然b字段也可能是a字段的; a字段也可能是b字段;
- 那么就直接掉头一下,拼接在一起;
- 分组聚合训练;
- 单组求TopN的求法
- 进阶解答:如果有第一,允许拿到并列的第一;
- 学习:知识的初次邂逅
- 复习:知识的温故知新
练习:知识的实践应用