SQL面试题4:相互关注问题
引言
在社交媒体和各类社区平台蓬勃发展的当下,用户之间的关系网络成为了平台运营和数据分析的关键部分。相互关注作为一种重要的社交关系,不仅反映了用户之间的紧密程度,还对平台的社交生态、内容传播等方面有着深远影响。本文将聚焦于 SQL 在处理相互关注问题上的应用,帮助大家深入理解如何通过 SQL 语言来分析和挖掘这类社交关系数据,为相关从业者应对面试以及实际工作中的数据处理需求提供有力支持。
场景介绍
(一)社交平台的发展与相互关注的重要性
如今,社交平台已经渗透到人们生活的方方面面。从以分享生活点滴为主的朋友圈,到专注于知识交流的知乎,再到以兴趣爱好为纽带的抖音等平台,用户数量数以亿计。在这些平台中,相互关注的关系构建起了一个个复杂的社交圈子。对于平台运营者而言,了解用户之间的相互关注情况,可以更好地进行用户画像分析、个性化推荐内容,提升用户体验和平台活跃度。例如,在电商社交平台上,相互关注的用户之间可能有着相似的购物偏好,平台可以根据这一特点向他们推荐相关商品,促进交易转化。对于内容创作者来说,粉丝之间的相互关注关系有助于内容的快速传播,扩大影响力。
(二)相互关注问题在数据分析中的价值
从数据分析的角度来看,相互关注数据蕴含着丰富的信息。通过分析相互关注的用户群体特征,可以发现不同兴趣群体的聚集模式,为市场细分提供依据。同时,研究相互关注关系的动态变化,如新增相互关注的趋势、某些用户群体之间相互关注的增长速度等,能够及时洞察平台社交生态的演变,为平台的战略决策提供数据支撑。
题目描述
现有一份用户关注关系的数据表,记录了用户之间的关注行为信息,包含以下字段:
follower_id:表示关注者的用户编号,用于唯一标识发起关注行为的用户。
followed_id:表示被关注者的用户编号,用于唯一标识受到关注的用户。
根据上述信息,需要完成以下任务:
- 统计平台上相互关注的用户对数。
- 分析每个用户拥有的相互关注好友数量,即有多少其他用户与该用户相互关注。
数据准备与代码实现
数据准备
CREATE TABLE follow_relation_tb (follower_id INT,followed_id INT
);INSERT INTO follow_relation_tb VALUES
(1, 2),
(2, 1),
(1, 3),
(3, 4),
(4, 3),
(5, 6);
1. 统计平台上相互关注的用户对数
思路一:自连接(常规思路)
- 思路:通过自连接,将原表与自身关联,匹配互为关注关系的记录。
- 注意:去重,确保每对相互关注用户数只出现一次。
SELECT COUNT(DISTINCT a.follower_id, a.followed_id) AS mutual_follow_count
FROM follow_relation_tb a
JOIN follow_relation_tb b ON a.follower_id = b.followed_id
AND a.followed_id = b.follower_id
# 去重,确保每对相互关注用户数只出现一次
WHERE a.follower_id < a.followed_id;
思路二:UNION ALL + 分组统计法
- 思路:将原表与反转后的表合并,统计每组用户对出现的次数为2的记录。
SELECT follower_id,followed_id
FROM (SELECT follower_id, followed_id, COUNT(*) AS cntFROM (SELECT follower_id, followed_id FROM follow_relation_tbUNION ALLSELECT followed_id, follower_id FROM follow_relation_tb) tGROUP BY follower_id, followed_idHAVING cnt = 2
) tmp
WHERE follower_id < followed_id;
思路三:排序拼接法(优化思路)
思路:将用户对按字典序拼接为统一格式,统计出现次数为2的记录。
SELECT distinct CASE WHEN user1 < user2 THEN user1 ELSE user2 END AS user1,CASE WHEN user1 > user2 THEN user1 ELSE user2 END AS user2
FROM (SELECT followed_id AS user1, follower_id AS user2,COUNT(*) OVER (PARTITION BY CONCAT_WS('-',CAST(LEAST(followed_id, follower_id) AS STRING),CAST(GREATEST(followed_id, follower_id) AS STRING))) AS cntFROM follow_relation_tb
) t
WHERE cnt >= 2;
思路四:哈希函数与窗口函数结合(高阶优化)
- 思路:通过哈希函数生成唯一标识,结合窗口函数判断是否存在互相关注。
- 具体步骤:先将用户对进行统一的哈希处理,然后统计每个用户对出现的次数,标记出相互关注的用户对,最后筛选出处于相互关注关系中的被关注者的 ID。
SELECT DISTINCT follower_id,followed_id
FROM (SELECT follower_id,followed_id, IF(COUNT(fan_pair) OVER (PARTITION BY fan_pair) >= 2, 1, 0) AS is_mutualFROM (SELECT followed_id,follower_id,IF(followed_id < follower_id, HASH(followed_id, follower_id), HASH(follower_id, followed_id)) AS fan_pairFROM follow_relation_tb) t
) t2
WHERE is_mutual = 1;
四种思路对比
| 时间复杂度 | 空间复杂度 | 适用场景 | 优缺点 | |
|---|---|---|---|---|
| 自连接法 | O(n²) | 高 | 小数据量,逻辑简单 | 优点:逻辑直观,适合数据量较小的场景 缺点:自连接可能导致数据膨胀,尤其在大数据量下性能较差。 |
| UNION ALL + 分组 | O(nlogn) | 中 | 大数据量,避免JOIN | 优点:避免JOIN操作,适合大数据场景 缺点:UNION ALL导致数据量翻倍,可能增加计算成本 |
| 排序拼接法 | O(n) | 低 | 超大数据量,需快速响应 | 仅需一次表扫描,利用窗口函数减少计算量 |
| 哈希与窗口函数结合 | O(n) | 低 | 海量数据,高性能要求 | 利用哈希函数减少字符串拼接开销,性能更优 |
2. 分析每个用户拥有的相互关注好友数量
步骤与思路:
- 先通过自连接找到所有相互关注的关系,
- 然后使用
GROUP BY对用户进行分组,再利用COUNT(DISTINCT)函数统计每个用户对应的相互关注好友数量。 - 注意:由于相互关注关系会在连接结果中出现两次(如用户 1 和用户 2 相互关注,会有(1, 2)和(2, 1)两条记录),所以在统计时要使用
DISTINCT避免重复计算。
SELECT a.follower_id AS user_id, COUNT(DISTINCT b.follower_id) AS mutual_follow_friends_count
FROM follow_relation_tb a
JOIN follow_relation_tb b ON a.follower_id = b.followed_id AND a.followed_id = b.follower_id
GROUP BY a.follower_id;
针对用户量较大的表处理相互关注问题的效率优化:索引优化和分区表
- 索引优化
在 follower_id 和 followed_id 列上创建复合索引。索引可以加快查询时的查找速度,因为数据库可以直接通过索引定位到符合条件的记录,而不需要全表扫描。
CREATE INDEX idx_follow_relation ON follow_relation_tb (follower_id, followed_id);
- 分区表
如果数据量非常大,可以考虑使用分区表。例如按照 follower_id 的范围进行分区,这样在查询时可以只扫描相关分区,减少扫描的数据量。
-- 创建分区表
CREATE TABLE follow_relation_tb (follower_id INT,followed_id INT
)
PARTITION BY RANGE (follower_id) (PARTITION p0 VALUES LESS THAN (1000),PARTITION p1 VALUES LESS THAN (2000),-- 可以根据实际情况添加更多分区PARTITION pn VALUES LESS THAN MAXVALUE
);
延伸问题
延伸问题1:如何避免重复记录(如(A,B)和(B,A)视为同一对)?
- 问题场景:查询结果中需要确保每对用户只出现一次(按字典序排列)。
- 优化点:
- 使用
LEAST和GREATEST标准化用户对顺序,避免重复。 - 通过
GROUP BY聚合减少数据量,结合HAVING筛选互关对。
- 使用
SELECTLEAST(followed_id, follower_id) AS user1,GREATEST(followed_id, follower_id) AS user2
FROM follow_relation_tb
GROUP BY user1, user2
HAVING COUNT(DISTINCT CASEWHEN followed_id = user1 THEN follower_idELSE followed_id
END) = 2;
延伸问题2:如何快速判断某个用户(如用户A)的互关用户列表
- 问题场景:给定用户A,高效查询与其互相关注的用户。
- 优化点:
- 为
(from_user, to_user)建立联合索引,避免全表扫描。 - 使用
IN子查询将操作转换为索引覆盖查询。
- 为
SELECTfollower_id AS mutual_user
FROM follow_relation_tb
WHERE followed_id = 'A'
AND follower_id IN (SELECT followed_idFROM follow_relation_tbWHERE follower_id = 'A'
);
其他
- 延伸问题3:如何统计全平台用户的平均互关率?
- 问题场景:计算所有用户中,存在互相关注的用户占比。
- 延伸问题4:如何在大数据量下分页查询互关用户对?
- 问题场景:分页查询互关用户列表(如每页1000条)。
- 优化点:
- 用ROW_NUMBER()生成游标替代OFFSET,避免深度分页的性能问题。
- 预先聚合互关对减少计算量。
- 延伸问题5:如何实时监控新产生的互关对?
- 问题场景:实时检测新产生的互关关系(如用于消息推送)。
- 优化点:
- 触发器确保实时性,但需注意高并发下的性能问题。
- 替代方案:通过消息队列异步处理,降低数据库压力。
高频优化技巧总结
- 索引设计:
必建索引:(from_user, to_user)的联合索引。
可选优化:为(LEAST(from_user, to_user), GREATEST(from_user, to_user))建立生成列索引。 - 避免全表扫描:
使用EXISTS替代IN子查询;通过覆盖索引减少回表操作。 - 分治策略:
按用户ID哈希分桶,并行处理不同桶的数据;使用分区表(如按时间或用户范围分区)。 - 内存优化:
调整数据库的sort_buffer_size和join_buffer_size;使用临时表存储中间结果。 - 业务妥协:
异步计算:非实时场景可将结果写入缓存表定期更新。
概率统计:使用APPROX_COUNT_DISTINCT等近似函数加速计算。
面试回答技巧
- 强调场景适配:如“如果数据量在千万级,我会优先选择分桶+哈希的方式”。
- 结合执行计划:提到
EXPLAIN分析索引使用情况。 - 容错设计:如处理重复数据、事务隔离级别的影响。
- 扩展思考:提及NoSQL方案(如Redis的集合操作)作为对比,体现技术广度。
相关文章:
SQL面试题4:相互关注问题
引言 在社交媒体和各类社区平台蓬勃发展的当下,用户之间的关系网络成为了平台运营和数据分析的关键部分。相互关注作为一种重要的社交关系,不仅反映了用户之间的紧密程度,还对平台的社交生态、内容传播等方面有着深远影响。本文将聚焦于 SQL…...
ArcGIS基础知识之ArcMap基础设置——ArcMap选项:常规选项卡设置及作用
作为一名 GIS 从业者,ArcMap 是我们日常工作中不可或缺的工具。对于初学者来说,掌握 ArcMap 的基础设置是迈向 GIS 分析与制图的第一步。今天,就让我们一起深入了解 ArcMap 选项中常规选项卡的各个设置,帮助大家更好地使用这款强大的软件。 在 ArcMap 中,常规选项卡是用户…...
jvm 线程监控调试
文章目录 前言一、使用JDK工具转储线程文件(如jstack)1. 找到Java进程的PID:2. 使用jstack生成线程转储文件:3.验证生成的线程转储文件:二、分析文件1.使用在线工具进行分析上传thread-dump文件,等待解析完成2.查看分析结果总结前言 提示:使用jdk自带工具转储线程监控文…...
25、深度学习-自学之路-卷积神经网络基于MNIST数据集的程序展示
import keras #添加Keraskuimport sys,numpy as np from keras.utils import np_utilsimport osfrom keras.datasets import mnist print("licheng:""20"\n) np.random.seed(1)(x_train,y_train),(x_test,y_test) mnist.load_data() #第一次…...
【C++】解锁<list>的正确姿势
> 🍃 本系列为初阶C的内容,如果感兴趣,欢迎订阅🚩 > 🎊个人主页:[小编的个人主页])小编的个人主页 > 🎀 🎉欢迎大家点赞👍收藏⭐文章 > ✌️ 🤞 …...
Qt中的事件
写一个 可以拖动的按钮 DraggablePushButton.h 头文件 #ifndef DRAGGABLEPUSHBUTTON_H #define DRAGGABLEPUSHBUTTON_H#include <QPushButton> #include <QMouseEvent>class DraggablePushButton : public QPushButton {Q_OBJECTpublic:explicit DraggablePushBu…...
变化检测相关论文可读list
一些用得上的: 遥感变化检测常见数据集https://github.com/rsdler/Remote-Sensing-Change-Detection-Dataset/ 代码解读:代码解读 | 极简代码遥感语义分割,结合GDAL从零实现,以U-Net和建筑物提取为例 NeurIPS2024: https://mp.w…...
Ansible中playbook的变量
变量 playbook的变量有以下几种 在playbook中用户自定义的变量远程主机中由Ansible收集的变量在文件模板中使用的上述两种变量把任务结果作为一个变量使用,叫注册变量用户在执行playbook时,通过命令行传入的变量,叫做额外变量 在playbook中…...
亚信安全正式接入DeepSeek
亚信安全致力于“数据驱动、AI原生”战略,早在2024年5月,推出了“信立方”安全大模型、安全MaaS平台和一系列安全智能体,为网络安全运营、网络安全检测提供AI技术能力。自2024年12月DeepSeek-V3发布以来,亚信安全人工智能实验室利…...
相似性图相关性重构网络用于无监督跨模态哈希
《Similarity Graph-correlation Reconstruction Network for unsupervised cross-modal hashing》 摘要1. 引言2. 相关工作2.1. 监督跨模态哈希方法2.2. 无监督跨模态哈希方法 3. 方法论3.1 问题定义3.2 特征提取3.3 模态内关系图构建3.4. 局部关系图重置3.5. 跨模态关系图构建…...
【Bug】属性 PackageVersion 应在所有目标框架中具有单个值,但却具有以下值
文章目录 问题问题代码原因解决处理Bug的具体步骤 问题 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) NU1105 无法读取“x”的项目信息: 属性 PackageVersion 应在所有目标框架中具有单个值,但却具有以下值: 1.0.0, 1.0.5 x (net8.0-android), x (net8.…...
C++ Primer 类型转换
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
【CS61A 2024秋】Python入门课,全过程记录P7(Week13 Macros至完结)【完结撒花!】
文章目录 关于新的问题更好的解决方案Week13Mon Macros阅读材料Lab 11: Programs as Data, MacrosQ1: WWSD: QuasiquoteQ2: If ProgramQ3: Exponential PowersQ4: Repeat Wed SQL阅读材料Disc 11: MacrosQ1: Mystery MacroQ2: Multiple AssignmentQ3: Switch Optional Contest:…...
SSH隧道+Nginx:绿色通道详解(SSH Tunnel+nginx: Green Channel Detailed Explanation)
SSH隧道Nginx:内网资源访问的绿色通道 问题背景 模拟生产环境,使用两层Nginx做反向代理,请求公网IP来访问内网服务器的网站。通过ssh隧道反向代理来实现,重点分析一下nginx反代的基础配置。 实验环境 1、启动内网服务器的tomca…...
LabVIEW用户界面设计原则
在LabVIEW开发中,用户界面(UI)设计不仅仅是为了美观,它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性,尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…...
Datawhale 数学建模导论二 2025年2月
第6章 数据处理与拟合模型 本章主要涉及到的知识点有: 数据与大数据Python数据预处理常见的统计分析模型随机过程与随机模拟数据可视化 本章内容涉及到基础的概率论与数理统计理论,如果对这部分内容不熟悉,可以参考相关概率论与数理统计的…...
SQL CASE表达式的用法
SQL CASE表达式的用法 一、CASE表达式的基础语法简单CASE表达式搜索CASE表达式 二、简单CASE表达式的应用示例三、搜索CASE表达式的应用示例四、CASE表达式在聚合函数中的应用五、嵌套CASE表达式的应用 今天在也无力用到了CASE表达式,于是有了这篇博客,C…...
趣味魔法项目 LinuxPDF —— 在 PDF 中启动一个 Linux 操作系统
最近,一位开源爱好者开发了一个LinuxPDF 项目(ading2210/linuxpdf: Linux running inside a PDF file via a RISC-V emulator),它的核心功能是在一个 PDF 文件中启动并运行 Linux 操作系统。它通过巧妙地使用 PDF 文件格式中的 Ja…...
win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一
;运行效果 ;win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一 ;生成2条横的跟踪条,分别设置不同的数值范围,设置不同的进度副度的例子 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>…...
mars3d接入到uniapp的时候ios上所有地图的瓦片都无法加载解决方案
用的是【Mars3d】官网的uniapp的仓库,安卓没有问题,但是ios的不行 相关链接 mars3d-uni-app: uni-app技术栈下的Mars3D项目模板 解决方案:感觉所有图片请求全被拦截了 uniapp的ios内核不允许跨域,需要先把瓦片下载后转base64&…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
