表:Follow
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| followee | varchar |
| follower | varchar |
+-------------+---------+
(followee, follower) 是该表的主键(具有唯一值的列的组合)。
该表的每一行表示关注者关注了社交网络上的被关注者。
不会有用户关注他们自己。
二级关注者 是指满足以下条件的用户:
- 关注至少一个用户,
- 被至少一个用户关注。
编写一个解决方案来报告 二级用户 及其关注者的数量。
返回按 follower 字典序排序的结果表。
结果格式如下所示。
示例 1:
输入:
Follow table:
+----------+----------+
| followee | follower |
+----------+----------+
| Alice | Bob |
| Bob | Cena |
| Bob | Donald |
| Donald | Edward |
+----------+----------+
输出:
+----------+-----+
| follower | num |
+----------+-----+
| Bob | 2 |
| Donald | 1 |
+----------+-----+
解释:
用户 Bob 有 2 个关注者。Bob 是二级关注者,因为他关注了 Alice,所以我们把他包括在结果表中。
用户 Donald 有 1 个关注者。Donald 是二级关注者,因为他关注了 Bob,所以我们把他包括在结果表中。
用户 Alice 有 1 个关注者。Alice 不是二级关注者,但是她不关注任何人,所以我们不把她包括在结果表中。
思路:
第一步,确定需要被统计的用户范围。用户是否"关注过别人"可以通过 follower 列判断,因此我们先从 Follow 表中取出所有出现过的 follower(去重后形成一个集合)。接着在原表中只保留那些 followee 落在该集合中的记录,这样筛出来的 followee 就是"既当过 follower 的用户",也就是题目要求的统计对象。
第二步,对筛选后的记录进行分组聚合。筛选条件执行后,表中剩下的每一行都表示"有人关注了某个符合条件的 followee"。因此只需要按 followee 分组,并对组内记录计数,得到该用户被关注的次数。计数时使用 COUNT(*) 更稳健,含义是统计关注关系记录的条数。
最后输出 followee 以及对应的关注次数即可。需要注意的是,SQL 中一个查询块只能有一个 GROUP BY 子句,因此只保留一次按 followee 分组即可;如果在 SELECT 中把 followee 起别名为 follower,也不意味着要再按 follower 分组,本质仍然是同一个字段。
代码:
sql
select
followee as follower,
count(follower) as num
from Follow
where followee in (select distinct follower from Follow)
group by followee
order by follower;

代码2:
sql
select
f.followee as follower,
count(*) as num
from follow f
where exists (
select 1
from follow x
where x.follower = f.followee
)
group by f.followee
order by f.followee;