我有一个friends
表格,如下所示
+------+--------+
| Name | Friend |
+------+--------+
| A | B |
| B | C |
| D | B |
| D | C |
| A | E |
| E | Z |
+------+--------+
我想为每个朋友找一个朋友。
为此,我编写了以下查询
SELECT a.Name as Friend,b.Friend as FOF
FROM friends a
JOIN friends b
ON a.Friend = b.Name
通过该查询,我得到部分正确的输出,如下所示
+--------+-----+
| Friend | FOF |
+--------+-----+
| A | C |
| D | C |
| A | Z |
+--------+-----+
在输出中,我得到{{1}为C
的{{1}}。(因为friend of friend
是D
的朋友,而D
是朋友B
),但C
也是B
的直接朋友。
所以我想更新查询以排除C
也是直接朋友
答案 0 :(得分:2)
一种简单的方法是添加not exists
:
SELECT f1.Name as Friend, f2.Friend as FOF
FROM friends f1 JOIN
friends f2
ON f1.Friend = f2.Name
WHERE NOT EXISTS (SELECT 1
FROM friends f
WHERE f.Name = f1.Name and f.Friend = f2.Friend
);
答案 1 :(得分:1)
如果SQL Server具有元组支持,查询将如何:
实时测试:http://sqlfiddle.com/#!17/14aec6/1
SELECT a.Name as Friend,b.Friend as FOF
FROM friends a
JOIN friends b ON a.Friend = b.Name
-- exclude fof if it is already in direct friends
WHERE (a.Name, b.Friend) NOT IN (select df.Name, df.Friend from friends df)
输出:
| friend | fof |
|--------|-----|
| A | C |
| A | Z |
由于派生表通常不需要与外部查询相关联,因此可以通过从派生表中删除别名来simplify。发挥作用:
WHERE (a.Name, b.Friend) NOT IN (select Name, Friend from friends)
由于SQL Server尚不支持,所以可以改用EXISTS
/ NOT EXISTS
。查看戈登的答案
答案 2 :(得分:1)
您只需要过滤掉那些也是直接朋友的结果。
方法:1 使用不存在
effect:
方法:2 ,使用不输入
SELECT f1.Name as Friend, f2.Friend as FOF
FROM friends f1 JOIN
friends f2
ON f1.Friend = f2.Name
WHERE not exists (SELECT * FROM friends f WHERE f.Name = f1.Name and f.Friend = f2.Friend);