首页 > 试题广场 > 网易云音乐推荐(网易校招笔试真题)
[编程题]网易云音乐推荐(网易校招笔试真题)
  • 热度指数:46806 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
假设云音乐数据库里面现在有几张如下简化的数据表:
关注follow表,第一列是关注人的id,第二列是被关注人的id,这2列的id组成主键
user_id follower_id
1 2
1 4
2 3

这张表的第一行代表着用户id为1的关注着id为2的用户
这张表的第二行代表着用户id为1的关注着id为4的用户
这张表的第三行代表着用户id为2的关注着id为3的用户

个人的喜欢的音乐music_likes表,第一列是用户id,第二列是喜欢的音乐id,这2列的id组成主键
user_id
music_id
1 17
2 18
2 19
3 20
4 17

这张表的第一行代表着用户id为1的喜欢music_id为17的音乐
....
这张表的第五行代表着用户id为4的喜欢music_id为17的音乐

音乐music表,第一列是音乐id,第二列是音乐name,id是主键
id music_name
17 yueyawang
18 kong
19 MOM
20 Sold Out

请你编写一个SQL,查询向user_id = 1 的用户,推荐其关注的人喜欢的音乐。
不要推荐该用户已经喜欢的音乐,并且按music的id升序排列。你返回的结果中不应当包含重复项
上面的查询结果如下:
music_name
kong
MOM


示例1

输入

CREATE TABLE `follow` (
`user_id` int(4) NOT NULL,
`follower_id` int(4) NOT NULL,
PRIMARY KEY (`user_id`,`follower_id`));

CREATE TABLE `music_likes` (
`user_id` int(4) NOT NULL,
`music_id` int(4) NOT NULL,
PRIMARY KEY (`user_id`,`music_id`));

CREATE TABLE `music` (
`id` int(4) NOT NULL,
`music_name` varchar(32) NOT NULL,
PRIMARY KEY (`id`));

INSERT INTO follow VALUES(1,2);
INSERT INTO follow VALUES(1,4);
INSERT INTO follow VALUES(2,3);

INSERT INTO music_likes VALUES(1,17);
INSERT INTO music_likes VALUES(2,18);
INSERT INTO music_likes VALUES(2,19);
INSERT INTO music_likes VALUES(3,20);
INSERT INTO music_likes VALUES(4,17);

INSERT INTO music VALUES(17,'yueyawang');
INSERT INTO music VALUES(18,'kong');
INSERT INTO music VALUES(19,'MOM');
INSERT INTO music VALUES(20,'Sold Out');

输出

kong
MOM
第一步:用户1关注了哪些人
select follower_id
from follow
where user_id=1
第二步:用户1喜欢的音乐
select music_id
from music_likes
where user_id=1
第三步:关注的那些人喜欢的音乐
select music_id
from music_likes
where user_id in (
    select follower_id
    from follow
    where user_id=1
)
第四步:除了用户1喜欢的音乐外,关注的那些人喜欢的其他音乐
select music_id
from music_likes
where user_id in (
    select follower_id
    from follow
    where user_id=1
) and music_id not in(
select music_id
from music_likes
where user_id=1
)
第五步:与音乐表联结
select distinct m.music_name
from music m join 
(
    select music_id
    from music_likes
    where user_id in (
        select follower_id
        from follow
        where user_id=1
    ) and music_id not in(
    select music_id
    from music_likes
    where user_id=1
)
)a
on a.music_id=m.id
order by m.id


编辑于 2021-05-28 22:22:15 回复(4)
注意要去重!
前面做的获得积分最多的人系列的题做到自闭,这道题很快做出来了,开心!
刷题下来有一个经验就是:一定要想好再写!确定思路了再写!千万不要在自己对题目的理解都一知半解的情况下胡乱写~
这道题的思路:先确定下我关注的人和我喜欢的音乐的id,并去掉我和关注的人都喜欢的id,再用music表将id对上名字,需要注意的是,可能我关注的人中喜欢的音乐有重叠,因此要对music_name去重~

select distinct t3.music_name
from follow t1, music_likes t2, music t3
where t1.follower_id = t2.user_id
and t2.music_id = t3.id
and t1.user_id =1 
and t2.music_id not in 
(select music_id
from music_likes
where user_id =1)
order by t3.id


发表于 2021-10-06 20:56:09 回复(3)
select distinct music_name
from follow a left join music_likes b on a.follower_id = b.user_id
left join music c on b.music_id = c.id
where a.user_id = 1
and b.music_id not in (
    select music_id
    from music_likes
    where user_id = 1
)
order by b.music_id;
发表于 2021-01-30 14:39:44 回复(1)
贡献一种新的解法,针对每一个表进行查询,像套娃一样的一个表一个表嵌套查询,主要在from语句后面

select distinct music_name
from (select music_id from music_likes where user_id in (select follower_id from follow where user_id=1)) as b left join
music m
on m.id=b.music_id
where m.id not in (select music_id from music_likes where user_id=1 )
order by m.id asc
编辑于 2021-05-11 15:32:33 回复(1)
select music_name
from music_likes ml left join music m on ml.music_id = m.id
where user_id in(select follower_id from follow where user_id = 1)
    and music_id not in(select music_id from music_likes where user_id = 1)
group by music_id
order by music_id;

发表于 2022-02-20 21:08:39 回复(1)
mysql里select distinct后面没有的列不能排序,所以得先去重,然后派生表再排序
select music_name from 
(select distinct  c.id,c.music_name from follow a join music_likes b on a.follower_id=b.user_id join music c on b.music_id=c.id
where a.user_id=1 and b.music_id not in (select music_id from music_likes where user_id=1)
) x order by id


发表于 2022-01-26 15:47:50 回复(1)
with res as (
    select music_id as id from music_likes where user_id in(
        select follower_id from follow where user_id=1
    ) and 
    music_id not in(
        select music_id from music_likes where user_id=1
    ) 
)


select music_name FROM music where id IN(select * from res);

发表于 2021-10-21 12:09:17 回复(1)
SELECT DISTINCT m.music_name
FROM music m,music_likes ml
WHERE m.id = ml.music_id 
AND ml.user_id IN (SELECT follower_id FROM follow WHERE user_id = 1)
AND m.id NOT IN (SELECT music_id FROM music_likes WHERE user_id = 1)
ORDER BY m.id

发表于 2021-10-21 10:35:43 回复(0)

 with t as (
    select d.user_id,d.music_id 
    from music_likes d 
    inner join music c 
    on d.music_id=c.id
     )
select distinct music_name from 
(select a.user_id, c.music_name,c.id
from follow a 
inner join music_likes b 
on a.follower_id=b.user_id
inner join music c 
on b.music_id=c.id
where a.user_id=1) a 
 where a.id not in 
 (select t.music_id from t where t.user_id=a.user_id)
order by a.id

发表于 2021-09-29 21:57:28 回复(0)
SELECT distinct m.music_name
FROM follow f, music_likes ml, music m
WHERE f.follower_id=ml.user_id and ml.music_id=m.id
and f.user_id=1
and m.id NOT IN (select music_id
                 from music_likes
                 where user_id=1)
ORDER BY m.id;

发表于 2021-10-20 10:58:13 回复(0)
with a1 as(
select music_id
from follow join music_likes on follower_id = music_likes.user_id
where follow.user_id = 1
),          #关注人喜欢音乐的ID
a2 as(
select music_id
from music_likes
where user_id=1
)           #自己喜欢的音乐ID
select music_name
from music
where id in (select * from a1)
and id not in (select * from a2)

发表于 2022-06-19 15:12:55 回复(0)
求助各位大佬们 为啥我写的代码结果一样 但是不通过呢???😔😔😔😔 用例通过到底是一个什么东东???
select 
music.music_name
from
(
	select DISTINCT
	o1.user_id,
  o1.music_id
	from 
		(select t1.user_id,t2.music_id 
			from follow t1 join music_likes t2 on t1.follower_id=t2.user_id) o1
			left  JOIN   
		(select distinct t1.user_id,t2.music_id 
			from follow t1 join music_likes t2 on t1.user_id=t2.user_id)o2
			on o1.user_id=o2.user_id and o1.music_id!=o2.music_id
		where o1.music_id!=o2.music_id 
)s1 
join music on s1.music_id=music.id
where s1.user_id=1
ORDER BY music.id 	

发表于 2021-11-14 22:51:44 回复(0)
select distinct music_name from follow f, music_likes m , music mu
    where f.follower_id = m.user_id and m.music_id  = mu.id
        and (f.user_id,m.music_id) not in
                (select user_id, music_id from music_likes)
        and f.user_id = 1
        order by mu.id

编辑于 2021-09-17 23:08:22 回复(0)
使用 not in 把本身喜欢的音乐排除
select distinct music_name
from follow f, music_likes m, music m1
where f.follower_id = m.user_id and m.music_id = m1.id and f.user_id = 1
and m1.id not in (select m1.id
                       from follow f, music_likes m, music m1
                       where f.user_id = m.user_id and m.music_id = m1.id and f.user_id = 1)
order by m1.id ASC

发表于 2021-04-16 14:42:14 回复(0)
以follow为主表,左连接另外两张表,得到关注者的歌单,再从其中剔除自己喜欢的音乐即可
select
    distinct m.music_name
from follow f
left join music_likes ml on f.follower_id=ml.user_id
left join music m on ml.music_id=m.id
where m.music_name not in (
    select 
        music_name
    from follow
    join music_likes on follow.user_id=music_likes.user_id
    join music on music_likes.music_id=music.id
    where follow.user_id=1
) and f.user_id=1
order by m.id


发表于 2021-01-08 17:38:27 回复(0)
select distinct(c.music_name)
from follow a
join music_likes b
on a.follower_id = b.user_id
join music c
on b.music_id = c.id
where a.user_id = 1
and c.music_name not in (
select music_name from follow a join music_likes b on a.user_id = b.user_id join music c on b.music_id = c.id
    where a.user_id = 1
)
order by c.id asc;
发表于 2021-01-07 18:11:02 回复(0)
分别查找 用户1 及其关注者喜欢的音乐,则最终的结果使用  IN 、NOT IN 寻找并排除
SELECT music_name
FROM music
WHERE id IN (SELECT DISTINCT music_id
            FROM music_likes
            WHERE user_id IN (SELECT follower_id
                                 FROM follow
                                 WHERE user_id=1))
      AND id NOT IN (SELECT DISTINCT music_id
                     FROM music_likes
                     WHERE user_id=1)
发表于 2021-03-11 22:54:13 回复(4)
select music_name
from music
where id IN (select distinct music_id
from music_likes
where user_id in (select follower_id
from follow
where user_id = 1))
and id not in (select music_id
from music_likes
where user_id = 1)
order by id;
利用子查询,但需要注意null的处理,最好使用NOT IN剔除自己喜欢的音乐,而不是<>。当自己没有喜欢的音乐时候,使用不等于进行剔除就可能出现问题。
编辑于 2021-02-16 21:07:47 回复(0)
select music_name
from music left join music_likes
on music.id = music_likes.music_id
left join follow on music_likes.user_id =follower_id
where follow.user_id = 1
and music_name not in (select music_name
from music left join music_likes
on music.id = music_likes.music_id
left join follow on music_likes.user_id =follow.user_id
where follow.user_id = 1)
group by music_id
order by music_id
这道题的难点在于distinct与order by 子句一起运行会报错,可以使用group by 子句代替distinct解决.
发表于 2022-01-11 16:41:13 回复(3)
一开始用了join。 发现order by和distinct冲突的问题。不好弄

然后参考了大佬的程序使用子查询做出来了
记录一下我学习到的东西

先给一下代码
select
music_name
from music
where id in 
(
    select music_id from music_likes where user_id in 
    (select follower_id from follow where user_id=1)
)
and id not in 
(
    select music_id from music_likes where user_id=1
)
order by id

  • 这个问题一个简单的地方在于确定user_id=1 算是方便了不少
  • 由于是直接从music里选取,所以id与music_name一一对应,既不用去重,而且还解决了order by与distinct不独立的问题
  • 大佬真的赞
发表于 2022-07-01 22:47:42 回复(0)
  • 二维码

    扫描二维码,关注牛客网

  • 二维码

    下载牛客APP,随时随地刷题