从表中检索二级友谊并排除一级朋友

时间:2015-09-09 15:48:08

标签: mysql sql database

我有一个表Friendship的表结构:

| user varchar(255) | friend varchar(255) |

如何查找二级朋友列表(即约翰是亚当的朋友,他是史蒂夫的朋友,所以史蒂夫是约翰的二级朋友)?

2 个答案:

答案 0 :(得分:1)

SELECT f2.friend AS FriendOfFriend
FROM Friendship f
INNER JOIN Friendship f2 ON f.friend = f2.user

您的问题中缺少一些细节,因此可能需要调整这些联接。我假设朋友也是用户。

答案 1 :(得分:0)

考虑以下四行样本数据:

| user | friend |
+------+--------+
| John  | Sam    |
| John  | Adam   |
| Adam  | Steve  |
| Steve | George |

在这个例子中,约翰是亚当的朋友,亚当是史蒂夫的朋友,所以约翰和史蒂夫是二级朋友。要做到这一点,我们必须首先得到所有John的朋友列表,如下所示:

SELECT friend
FROM friendship
WHERE user = 'John';

请注意,这使得“John”始终是用户的假设。如果John有时候是“朋友”,那么你需要一个工会来获得完整的清单。

现在,我们列出了Adam和Sam的名单。我们需要得到他们的朋友列表。我们可以通过另一次加入来做到这一点:

SELECT f.friend AS firstLevel, fs.friend AS secondLevel
FROM friendship f
JOIN friendship fs ON fs.user = f.friend AND f.user = 'John';

这将为我们提供约翰二级朋友的名单,以及第一级朋友的名单。现在,有几件事需要考虑:

如果同一个朋友出现两次怎么办?让我们说,山姆也是史蒂夫的朋友。我们将获得以下行:

| Adam | Steve |
| Sam  | Steve |

为避免这种情况,我们可以将我们的选择取消给二级朋友并使用DISTINCT关键字:

SELECT DISTINCT fs.friend
FROM friendship f
JOIN friendship fs ON fs.user = f.friend AND f.user = 'John';

如果您需要进一步扩展,可以添加另一个连接,并确保它与前一个连接相关。因此,要获得第三级连接(在此示例中为George),我们可以使用以下查询:

SELECT DISTINCT fss.friend AS thirdLevel
FROM friendship f
JOIN friendship fs ON fs.user = f.friend AND f.user = 'John'
JOIN friendship fss ON fss.user = fs.friend;

上述所有示例都在此SQL Fiddle上进行了演示。