描述

假设云音乐数据库里面现在有几张如下简化的数据表:
关注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