SQL互粉问题

        本以为自己已经会了很多的SQL类型题,但是前两天朋友面试时候问了一个互粉的SQL问题。

原题总共有三题:

  1. 请输出:互粉关系的用户有多少对?
  2. 求出截止到某一日期的互粉对的数量
  3. 求出2023年的截止到每一天的总的互粉用户数量 
create table if not exists test1.fans
(
fans_uid varchar(255),
uid varchar(255),
create_date date
);

INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (4, 1, '2022-11-09');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (1, 2, '2023-01-02');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (1, 3, '2023-01-05');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (2, 1, '2023-01-09');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (3, 1, '2023-02-08');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (1, 4, '2023-11-09');
INSERT INTO test1.fans (fans_uid, uid, create_date)
VALUES (1, 5, '2023-11-09');

 第一题:(总共想出来了三种方法)

# 法1
with t1 as(select fans_uid, uid,
       if(uid < fans.fans_uid,concat(uid,fans_uid),concat(fans_uid,uid)) as d
from test1.fans)
,t2 as (select count(d) as cnt
from t1
group by d
having cnt = 2)
select count(cnt) as total
from t2;

# todo 法2
with t1 as(
select fans_uid, uid from fans
union all
select uid ,fans_uid  from fans)
,t2 as (
select fans_uid, uid from fans
union
select uid ,fans_uid  from fans
)
,t3 as(select count(uid) as total from t1)
,t4 as(select count(uid) as cnt from t2)
select round((total - cnt)/2,0) as '互关'
from t3,t4
;

# todo 法3(可能是递归写的有问题,一直卡在运行界面)
with recursive t1 as (
    select uid,fans_uid from fans where uid = 1
    union all
    select t1.uid, concat(fans.uid,'->',t1.fans_uid)
    from t1 inner join fans on t1.uid = fans.fans_uid
    )
select *
from t1
;

第三种方法我是用递归求解的,但是电脑性能跟不上,运行了5分钟还是运行不出来

第二题:

with t1 as(select fans_uid, uid,create_date,
       if(uid < fans.fans_uid,concat(uid,fans_uid),concat(fans_uid,uid)) as d
from test1.fans
    order by d
    )
,t2 as (select fans_uid, uid, create_date, d,
       row_number() over (partition by d order by create_date) as rn
from t1)
select  create_date,
       sum(if(rn,1,0)) over(order by create_date) as cnt
from t2
where rn=2
;

第三题:(这个是最让我头疼的,就是因为这个我才知道有了 recursive 递归方法)

# 在这里边最重要的是使用递归求解连续日期 
with recursive t as (
    select date('2023-01-01') as dt,null as cnt
    union all
    select date_add(dt,interval 1 day), cnt from t where dt < date(current_date)
)
     ,t1 as(select fans_uid, uid,create_date,
       if(uid < fans.fans_uid,concat(uid,fans_uid),concat(fans_uid,uid)) as d
from test1.fans
    order by d
    )
,t2 as (select fans_uid, uid, create_date, d,
       row_number() over (partition by d order by create_date) as rn
from t1)
,t3 as (select  create_date,
       sum(if(rn,1,0)) over(order by create_date) as cnt
from t2
where rn=2)
select dt,
       if(t.cnt is null ,t3.cnt,t.cnt) as cnt
       # coalesce(t.cnt,t3.cnt)
from t left join t3
on t.dt=t3.create_date;

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yangjiwei0207

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值