首页 > 解决方案 > 优化查询以在 Facebook 中查找共同好友

问题描述

假设 Facebook 朋友的表如下所示 - userId | friendId,您将如何编写 SQL 查询来查找两个朋友之间的共同朋友?我有下面的代码适用于两个朋友 A 和 B。但是,我觉得它没有得到足够的优化,我希望我可以用 join 做同样的查询。我感到困惑的两个领域:

  1. 特定的用户 ID 可以在任一列中,具体取决于发起好友请求的人。如果 A 向 B 发送请求,userId 将是 A,friendId 将是 B。下面的查询我已经处理了这种情况,但是你将如何对 JOIN 做同样的事情?
  2. FB如何推荐添加某人为朋友?在查询中会是什么样子?

Stack Overflow/互联网上有多个类似的问题,但似乎没有一个是 100% 准确的!

我正在寻找一个 MS SQL 服务器查询,但任何 SQL 语言都应该可以工作。

SELECT *
FROM (
SELECT CASE WHEN userId = 'A' THEN friendId ELSE userId END AS mutualFriends
FROM friendsTable 
WHERE userId = 'A' OR friendId = 'A'
UNION
SELECT CASE WHEN userId = 'B' THEN friendId ELSE userId END AS mutualFriends
FROM friendsTable 
WHERE userId = 'B' OR friendId = 'B'
) A
WHERE mututalFriends NOT IN ('A','B')

标签: sqlfacebookmutual-friendship

解决方案


您提供的查询是一个 UNION,它返回 A 和 B 的朋友的并集。

下面的查询返回 A 和 B 的朋友的 JOIN - A 和 B 的朋友列表。

小提琴: DB-Fiddle

SELECT a_mutualfriendid AS mutualfriendid FROM 

(SELECT distinct a_mutualfriendid
FROM (SELECT 
  case 
    when userid = 'A' then friendid 
    else userid 
  end as a_mutualfriendid
FROM friendsTable
WHERE userid in ('A') or friendid in ('A')
) a_friends
WHERE a_mutualfriendid NOT IN ('B')) a

INNER JOIN

(SELECT distinct b_mutualfriendid
FROM (SELECT 
  case 
    when userid = 'B' then friendid 
    else userid 
  end as b_mutualfriendid
FROM friendsTable
WHERE userid in ('B') or friendid in ('B')
) b_friends
WHERE b_mutualfriendid NOT IN ('A')) b

ON a_mutualfriendid = b_mutualfriendid

至于 Facebook 如何存储数据,这是专有信息,员工可能无法回答。

这里有一个猜测:记住如果 X 是 Y 的朋友,他们中的任何一个都可以“忽略”另一个,数据库中可能有两条记录,“X 与 Y 的朋友”和“Y 与 X 的朋友”。来自 X 的初始请求创建第一条记录,来自 Y 的接受操作创建第二条记录。然后,每条记录都可以存储来自朋友的帖子是否应该显示在其他人的提要中。


推荐阅读