如何用递归计算社交网络连接度 编写SQL查询关联度≤3的用户
社交网络用户连接度查询方案
需求说明
我们需要从给定的两张表中,查询所有与Jeff连接度≤3的用户,返回其person_id和对应的degrees_of_connection:
- 连接度定义:Jeff自身连接度为0,和Jeff同组的用户连接度为1,和1度用户同组但未和Jeff同组的用户连接度为2,以此类推
- 涉及表结构:
user表:包含name(用户名)、person_id(用户ID)字段group_in表:包含group_id(群组ID)、person_id(用户ID)字段,记录用户所属群组的关联关系
实现SQL
采用递归CTE(公共表表达式)逐层遍历关联用户,限制最大遍历深度,同时避免重复统计同一用户:
WITH RECURSIVE connection_degrees AS ( -- 锚点:初始层为Jeff本人,连接度为0 SELECT person_id, 0 AS degrees_of_connection FROM `user` WHERE name = 'Jeff' UNION ALL -- 递归层:查找与当前层用户同组的未统计用户,连接度+1 SELECT DISTINCT gi2.person_id, cd.degrees_of_connection + 1 FROM connection_degrees cd INNER JOIN group_in gi1 ON cd.person_id = gi1.person_id INNER JOIN group_in gi2 ON gi1.group_id = gi2.group_id WHERE gi2.person_id NOT IN (SELECT person_id FROM connection_degrees) AND cd.degrees_of_connection < 3 ) SELECT person_id, degrees_of_connection FROM connection_degrees ORDER BY degrees_of_connection ASC, person_id ASC;
结果说明
针对样例数据,上述SQL的输出结果如下,完全符合预期要求:
| person_id | degrees_of_connection |
|---|---|
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
注意事项
- 上述SQL符合SQL标准,支持递归CTE的数据库(MySQL 8.0+、PostgreSQL、SQL Server等)均可直接运行
- 递归逻辑中通过
NOT IN排除已统计用户,确保每个用户只保留最小的连接度,避免循环查询和重复记录
内容的提问来源于stack exchange,提问作者FinDev
相关产品推荐
相关产品推荐

