描述
假设云音乐数据库里面现在有几张如下简化的数据表:
关注follow表,第一列是关注人的id,第二列是被关注人的id,这2列的id组成主键
这张表的第一行代表着用户id为1的关注着id为2的用户
这张表的第二行代表着用户id为1的关注着id为4的用户
这张表的第三行代表着用户id为2的关注着id为3的用户
个人的喜欢的音乐music_likes表,第一列是用户id,第二列是喜欢的音乐id,这2列的id组成主键
这张表的第一行代表着用户id为1的喜欢music_id为17的音乐
....
这张表的第五行代表着用户id为4的喜欢music_id为17的音乐
音乐music表,第一列是音乐id,第二列是音乐name,id是主键
请你编写一个SQL,查询向user_id = 1 的用户,推荐其关注的人喜欢的音乐。
不要推荐该用户已经喜欢的音乐,并且按music的id升序排列。你返回的结果中不应当包含重复项
上面的查询结果如下:
关注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 | +------------+
输入:
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');
解题:
创建2个新表,然后合并
合并后的表再 关联最后有music name的表
个人比较喜欢 WITH ... AS 来创建子表
WITH user_music AS (SELECT follow.user_id, music_likes.music_id FROM follow LEFT JOIN music_likes ON follow.user_id = music_likes.user_id ), follower_music AS (SELECT follow.follower_id, music_likes.music_id FROM follow LEFT JOIN music_likes ON follow.follower_id = music_likes.user_id ), combine AS (SELECT follow.user_id, follow.follower_id, user_music.music_id AS u_music_id, follower_music.music_id AS f_music_id FROM follow LEFT JOIN user_music ON follow.user_id = user_music.user_id LEFT JOIN follower_music ON follow.follower_id = follower_music.follower_id WHERE follow.user_id = 1 ) SELECT DISTINCT music_name FROM music, combine WHERE music.id = combine.f_music_id AND combine.f_music_id != combine.u_music_id ORDER BY music.id