【MySQL】巧妙关联之页面推荐(推荐好友喜欢,自己不喜欢的页面给自己)

力扣题

1、题目地址

1892. 页面推荐Ⅱ

2、模拟表

表:Friendship

Column NameType
user1_idint
user2_idint
  • (user1_id,user2_id) 是 Friendship 表的主键(具有唯一值的列的组合)。
  • 该表的每一行表示用户user1_id和user2_id是好友。

表:Likes

Column NameType
user_idint
page_idint
  • (user_id,page_id) 是 Likes 表的主键(具有唯一值的列)。
  • 该表的每一行表示user_id喜欢page_id。

3、要求

您正在为一个社交媒体网站实施一个页面推荐系统。
如果页面被user_id的 至少一个朋友喜欢 ,而 不被user_id喜欢 ,你的系统将 推荐 一个页面到user_id。

编写一个解决方案来查找针对每个用户的所有可能的 页面建议 。
每个建议应该在结果表中显示为一行,包含以下列:

user_id:系统向其提出建议的用户的ID。
page_id:推荐为 user_id 的页面ID。.
friends_likes:user_id 对应 page_id 的好友数。
以 任意顺序 返回结果表。

4、示例

输入:

Friendship 表:

user1_iduser2_id
12
13
14
23
24
25
61

Likes 表:

user_idpage_id
188
223
324
456
511
633
277
377
688

输出:

user_idpage_idfriends_likes
1772
1231
1241
1561
1331
2241
2561
2111
2881
3881
3231
4881
4771
4231
5771
5231

解释:

以 用户1 为例:

  • 用户1 是 用户 2、3、4、6 的好友。
  • 推荐页面有 23(用户2喜欢),24(用户3喜欢),56(用户3喜欢),33(用户6喜欢),77(用户2和用户3喜欢)。
  • 请注意,第 88 页不推荐,因为 用户1 已经喜欢它。

另一个例子是 用户 6:

  • 用户6 是 用户1 的好友。
  • 用户1 只喜欢了 88 页,但 用户6 已经喜欢了。因此,用户6 没有推荐。

您可以使用类似的过程为 用户 2、3、4 和 5 推荐页面。

代码编写

网友代码

1、tmp 表找出所有的朋友关系对,tmp 跟 Likes one 用 two.user_id 和 one.user_id 相关联,那么 one.friend_id 就是被推荐的用户。

2、这时候我们需要排除 two.friend_id 已经 Likes 过的推荐。这里比较自然而然想到的方式是 (friend_id, page_id) not in (select user_id,page_id from Likes) ,但是会发现这个效率太慢了,在 MySQL 下通过不了,所以转而使用表连接的方式。

3、我们再次用 Likes three 跟 tmp two 表做关联,令 three.page_id = one.page_id,这时候会发现,two.friend_id 没有 Likes 过的推荐全部变成了 null。(这一点很关键,要多想)

4、那么最后把 null 的记录排除,再做一个分组聚合即可。

with tmp as(
    select user1_id AS user_id, user2_id AS friend_id from Friendship
    union all
    select user2_id, user1_id from Friendship
)
select two.friend_id AS user_id, 
       one.page_id,
       count(1) friends_likes
from Likes one
    	left join tmp two on one.user_id = two.user_id
    	left join Likes three on three.user_id = two.friend_id and three.page_id = one.page_id
where three.page_id is null
group by 1, 2
order by 1, 3 desc, 2
  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值