相互关注SQL写法(5种不同类型写法)

背景

群友字节面试让写出3种方法,但只写出2种最后面试没过,相互关注是常见一道SQL题,但这次我们加一下挑战难度,通过不同sql方法去解(不考虑时效),且之前用过的方法后续不会再用,比较考察SQL的基本功。

题目

现在有一张表为fans(粉丝表) 里面有两个字段from_user,to_user ,如果两者一致代表from_user关注了to_user

数据

with fans as (
SELECT 
    '001' as from_user,'002' as to_user
union all 
SELECT 
    '002' as from_user,'001' as to_user
union all 
SELECT 
    '003' as from_user,'001' as to_user
union all 
SELECT 
    '005' as from_user,'001' as to_user
)

解法1:关联(scan2次)

select t1.from_user
from fans t1 
 join 
fans t2 
on t1.from_user=t2.to_user 
and t1.to_user=t2.from_user
;

from_user

001

002

解法2:关联(scan2次)

select u1 from 
(
select from_user u1,to_user u2 from fans 
union all 
select to_user u1,from_user u2 from fans 
) a 
group by u1,u2 having count(1)=2
;

U1

001

002

解法3:开窗(scan1次),最优,要的就是这个答案

select from_user
from
(
select
from_user,
if(count(fans_user) over (partition by fans_user) > 1, 1,0) as is_fans
from 
(
select if(hash(from_user)>hash(to_user),concat(from_user,'-',to_user),concat(to_user,'-',from_user)) fans_user
      ,from_user
from fans
) 
)
where is_fans=1
;

from_user

001

002

解法4:炸裂(posexplode),用index去匹配,问题在于数据量级膨胀

select count(*)
      ,fans2
      ,fans1
from (
SELECT 
    t1.fans1 ,
    t2.fans2 
FROM (
    SELECT 
        CONCAT(from_user,'-',to_user) AS fan1,
        CONCAT(to_user,'-',from_user) AS fan2,
        from_user
    FROM fans
) as temp_table
LATERAL VIEW posexplode(split(temp_table.fan1,'-')) t1 AS fans_index1,fans1
LATERAL VIEW posexplode(split(temp_table.fan2,'-')) t2 AS fans_index2,fans2
WHERE t1.fans_index1 = t2.fans_index2
)
group by fans2
        ,fans1
having count(*)=2

cnt

fans2

fans1

2

002

001

2

001

002

解法5:集合排序(sort_array),通过拼接collect_list形成list,再去切割排序

SELECT count(sort_array(split(user_fans,'-'))) as cnt
      ,sort_array(split(user_fans,'-')) as fans_list
from (
SELECT concat_ws(',',COLLECT_LIST(concat(from_user,'-',to_user))) as user_fans
      ,from_user
FROM fans
group by from_user
) GROUP BY sort_array(split(user_fans,'-'))
having count(sort_array(split(user_fans,'-')))=2

cnt

fans_list

2

[001,002]

#sql练习日常##数据人的面试交流地##24届软开秋招面试经验大赏##牛客创作赏金赛##数据分析#
全部评论

相关推荐

2025-12-15 14:25
云南大学 Java
lei22:入职可能会看学信网,最好别伪装,这个简历找实习肯定是够的,肯定会有收 28 届实习生的公司的,多投就行
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2025-12-17 16:48
今天九点半到公司,我跟往常一样先扫了眼电脑,屁活儿没有。寻思着没事干,就去蹲了个厕所,回来摸出手机刷了会儿。结果老板刚好路过,拍了我一下说上班别玩手机,我吓得赶紧揣兜里。也就过了四十分钟吧,我的直属领导把我叫到小隔间,上来就给我一句:“你玩手机这事儿把老板惹毛了,说白了,你可以重新找工作了,等下 HR 会来跟你谈。” 我当时脑子直接宕机,一句话都没憋出来。后面 HR 找我谈话,直属领导也在旁边。HR 说我这毛病不是一次两次了,属于屡教不改,不光上班玩手机,还用公司电脑看论文、弄学校的事儿。我当时人都傻了,上班摸鱼是不对,可我都是闲得发慌的时候才摸啊!而且玩手机这事儿,从来没人跟我说过后果这么严重,更没人告诉我在公司学个习也算犯错!连一次口头提醒都没有,哪儿来的屡教不改啊?更让我膈应的是,昨天部门刚开了会,说四个实习生里留一个转正,让大家好好表现。结果今天我就因为玩手机被开了。但搞笑的是,开会前直属领导就把我叫去小会议室,明明白白告诉我:“转正这事儿你就别想了,你的学历达不到我们部门要求,当初招你进来也没打算给你这个机会。”合着我没入贵厂的眼是吧?可我都已经被排除在转正名单外了,摸个鱼至于直接把我开了吗?真的太离谱了!
rush$0522:转正名单没进,大概率本来就没打算留你
摸鱼被leader发现了...
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务