订阅更新

页面推荐:朋友喜欢、而我还没喜欢的页面

SQL 实战 123 题 · 第 85 题 中等 约 2 分钟读完

LeetCode 1264 · 双向关系、IN / NOT IN、去重

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

朋友关系是无向的,所以用 CASE WHEN user1_id = 1 THEN user2_id ELSE user1_id END 在两种存储方向里都取出朋友;再取朋友喜欢的页面,NOT IN 排除 1 号已喜欢的,DISTINCT 去重。存储方向不固定的关系,都要先「对称化」再用。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

好友表每行是一对好友(顺序不固定),喜欢表记录用户喜欢的页面。给 1 号用户推荐他的朋友们喜欢、但他自己还没喜欢的页面,不要重复。

表结构

  • Friendship:user1_id、user2_id;(user1_id, user2_id) 为主键
  • Likes:user_id、page_id;(user_id, page_id) 为主键

思路

先找出 1 号用户的所有朋友:好友关系可能存成 (1, x) 也可能存成 (x, 1),两种都要取另一端。再取这些朋友喜欢的页面,排除 1 号自己已经喜欢的,最后去重。

参考解法

select distinct page_id  recommended_page
from Likes
where user_id in(
select if(user1_id=1,user2_id,user1_id) user_id
from  Friendship
where  user1_id =1 or user2_id =1
)
and page_id not in (select page_id from Likes where user_id=1)

易错点

  • 只查 user1_id = 1 会漏掉存成 (x, 1) 的好友。
  • NOT IN 的子查询理论上要防 NULL,这里 page_id 是主键的一部分不会为空。
刷题进度保存在当前浏览器