题目描述
(通过次数10,309 | 提交次数17,975,通过率57.35%)
朋友关系列表:Friendship +---------------+---------+ | Column Name | Type | +---------------+---------+ | user1_id | int | | user2_id | int | +---------------+---------+ 这张表的主键是 (user1_id, user2_id)。 这张表的每一行代表着 user1_id 和 user2_id 之间存在着朋友关系。 喜欢列表:Likes +-------------+---------+ | Column Name | Type | +-------------+---------+ | user_id | int | | page_id | int | +-------------+---------+ 这张表的主键是 (user_id, page_id)。 这张表的每一行代表着 user_id 喜欢 page_id。 写一段 SQL 向user_id = 1 的用户,推荐其朋友们喜欢的页面。不要推荐该用户已经喜欢的页面。 你返回的结果中不应当包含重复项。 返回结果的格式如下例所示。 示例 1: 输入: Friendship table: +----------+----------+ | user1_id | user2_id | +----------+----------+ | 1 | 2 | | 1 | 3 | | 1 | 4 | | 2 | 3 | | 2 | 4 | | 2 | 5 | | 6 | 1 | +----------+----------+ Likes table: +---------+---------+ | user_id | page_id | +---------+---------+ | 1 | 88 | | 2 | 23 | | 3 | 24 | | 4 | 56 | | 5 | 11 | | 6 | 33 | | 2 | 77 | | 3 | 77 | | 6 | 88 | +---------+---------+ 输出: +------------------+ | recommended_page | +------------------+ | 23 | | 24 | | 56 | | 33 | | 77 | +------------------+ 解释: 用户1 同 用户2, 3, 4, 6 是朋友关系。 推荐页面为:页面23 来自于 用户2, 页面24 来自于 用户3, 页面56 来自于 用户3 以及 页面33 来自于 用户6。 页面77 同时被 用户2 和 用户3 推荐。 页面88 没有被推荐,因为 用户1 已经喜欢了它。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/page-recommendations
//测试数据 Create table If Not Exists Friendship (user1_id int, user2_id int); Create table If Not Exists Likes (user_id int, page_id int); insert into Friendship (user1_id, user2_id) values ('1', '2'); insert into Friendship (user1_id, user2_id) values ('1', '3'); insert into Friendship (user1_id, user2_id) values ('1', '4'); insert into Friendship (user1_id, user2_id) values ('2', '3'); insert into Friendship (user1_id, user2_id) values ('2', '4'); insert into Friendship (user1_id, user2_id) values ('2', '5'); insert into Friendship (user1_id, user2_id) values ('6', '1'); insert into Likes (user_id, page_id) values ('1', '88'); insert into Likes (user_id, page_id) values ('2', '23'); insert into Likes (user_id, page_id) values ('3', '24'); insert into Likes (user_id, page_id) values ('4', '56'); insert into Likes (user_id, page_id) values ('5', '11'); insert into Likes (user_id, page_id) values ('6', '33'); insert into Likes (user_id, page_id) values ('2', '77'); insert into Likes (user_id, page_id) values ('3', '77'); insert into Likes (user_id, page_id) values ('6', '88');
解题思路
根据题目要求,返回满足下列两个条件的页面:
(1)、user_id=1的用户的朋友喜欢的页面;
(2)、user_id=1的用户未标记为喜欢的页面;
对于第一个条件,我们需要先计算出user_id=1的用户的朋友是哪些。
Friendship表保存了朋友关系,因此可以从该表获取数据。不过,A与B是朋友关系,B与A同样也是朋友关系。也就是说,朋友关系是相互的。所以,可以通过如下SQL获取user_id=1的用户的朋友:
select distinct case when user1_id = 1 then user2_id else user1_id end user_id from Friendship where user1_id = 1 or user2_id = 1;
对于第二个条件,相当于从第一个条件过滤出的页面中,剔除已经被user_id=1的用户标记为喜欢的页面。使用NOT IN或NOT EXISTS都可以很容易的实现。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
with tmp as ( select distinct case when user1_id = 1 then user2_id else user1_id end user_id from Friendship where user1_id = 1 or user2_id = 1 ) select distinct a.page_id recommended_page from Likes a inner join tmp b on a.user_id = b.user_id where not exists ( select 1 from Likes c where c.user_id = 1 and a.page_id = c.page_id);
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。