☰
LeetCode 614:SQL多表关联实现二级关注者统计
2026/10/26 16:21:39 网站建设 项目流程

1. 题目背景与需求分析

今天我们来拆解LeetCode数据库题目614号"二级关注者"(Second Degree Follower)。这是一道考察SQL多表关联和分组统计的中等难度题目,在实际业务场景中也非常常见——社交网络中的好友推荐系统、内容分发系统的潜在受众分析等场景都会用到类似的逻辑。

题目核心需求是:找出所有被至少两个人关注的二级关注者。这里的"二级关注者"定义需要特别注意——不是直接关注你的人,而是你关注的人所关注的那些用户。举个例子:如果用户A关注了用户B,用户B又关注了用户C,那么对A来说,C就是二级关注者。

2. 数据模型理解与表结构设计

首先我们需要理解题目给出的数据模型。根据LeetCode题目描述,主要涉及一张表:

CREATE TABLE follow ( followee VARCHAR(255), follower VARCHAR(255), PRIMARY KEY(followee, follower) )

这个表结构非常简单但信息量足够:

  • followee:被关注者
  • follower:关注者
  • 联合主键确保不会出现重复的关注关系

在实际业务中,这样的设计能有效防止用户重复关注同一个对象。值得注意的是,这个模型是单向关注关系(类似Twitter),而不是双向好友关系(类似微信)。

3. 解题思路拆解

要解决这个问题,我们需要分步骤思考:

3.1 第一步:找出所有二级关注关系

我们需要先找出每个人的二级关注者。这需要做一次自连接:

SELECT f1.follower AS user, f2.followee AS second_degree_follower FROM follow f1 JOIN follow f2 ON f1.followee = f2.follower

这个查询的逻辑是:

  1. f1表记录用户直接关注的人(一级关系)
  2. f2表记录一级关注者所关注的人(二级关系)
  3. 通过f1.followee = f2.follower的连接条件,建立二级关系链

3.2 第二步:统计每个二级关注者的关注人数

接下来我们需要对上述结果进行分组统计:

SELECT second_degree_follower AS follower, COUNT(DISTINCT user) AS num FROM ( SELECT f1.follower AS user, f2.followee AS second_degree_follower FROM follow f1 JOIN follow f2 ON f1.followee = f2.follower ) AS t GROUP BY second_degree_follower

这里有几个关键点:

  1. 使用DISTINCT确保同一个用户不会被重复计算
  2. 统计每个二级关注者被多少不同的用户间接关注
  3. 使用子查询使逻辑更清晰

3.3 第三步:筛选符合条件的记录

最后我们只需要筛选出被至少2人关注的二级关注者:

SELECT second_degree_follower AS follower, num FROM ( SELECT second_degree_follower, COUNT(DISTINCT user) AS num FROM ( SELECT f1.follower AS user, f2.followee AS second_degree_follower FROM follow f1 JOIN follow f2 ON f1.followee = f2.follower ) AS t1 GROUP BY second_degree_follower ) AS t2 WHERE num >= 2

4. 优化与变体思考

4.1 性能优化考虑

在实际大数据量场景下,这个查询可能会有性能问题。我们可以考虑以下优化:

  1. 索引优化:确保(followee,follower)和(follower,followee)都有复合索引
  2. 避免DISTINCT:如果业务允许,可以考虑用其他方式去重
  3. 使用CTE提高可读性:
WITH second_degree AS ( SELECT f1.follower AS user, f2.followee AS second_degree_follower FROM follow f1 JOIN follow f2 ON f1.followee = f2.follower ) SELECT second_degree_follower AS follower, COUNT(DISTINCT user) AS num FROM second_degree GROUP BY second_degree_follower HAVING COUNT(DISTINCT user) >= 2

4.2 业务场景扩展

这个模式可以扩展到很多实际业务场景:

  1. 社交推荐系统:基于共同关注推荐可能认识的人
  2. 内容分发:找出用户可能感兴趣的二级关系内容
  3. 风险控制:识别潜在的虚假账号网络

5. 常见错误与调试技巧

在解决这类问题时,新手常犯的错误包括:

  1. 忽略自连接的本质:忘记连接条件会导致笛卡尔积
  2. 错误理解关系方向:混淆follower和followee的角色
  3. 重复计数:忘记使用DISTINCT导致重复统计
  4. 筛选条件位置错误:把HAVING条件误放在WHERE中

调试技巧:

  • 先单独运行最内层查询,验证基础关系
  • 逐步添加外层逻辑,每步检查中间结果
  • 使用LIMIT限制结果集大小进行快速验证

6. 完整解决方案

综合以上分析,最终的解决方案如下:

SELECT follower, num FROM ( SELECT second_degree_follower AS follower, COUNT(DISTINCT user) AS num FROM ( SELECT f1.follower AS user, f2.followee AS second_degree_follower FROM follow f1 JOIN follow f2 ON f1.followee = f2.follower WHERE f1.follower != f2.followee -- 避免自关注的情况 ) AS t1 GROUP BY second_degree_follower ) AS t2 WHERE num >= 2 ORDER BY follower

这个方案增加了两个优化:

  1. 添加了WHERE条件排除用户关注自己的情况
  2. 增加了ORDER BY使结果更规整

7. 实际业务中的应用思考

在实际工程实践中,这类查询往往需要进一步优化:

  1. 预计算:对于不常变动的社交关系,可以定期预计算并存储结果
  2. 图数据库:超大规模关系网络更适合使用Neo4j等图数据库
  3. 批处理:可以设计增量更新的批处理作业,避免全量计算

对于LeetCode这样的平台,理解基础SQL模式是关键,但在实际工作中,我们需要根据数据规模和业务需求选择合适的实现方式。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询