我知道在这个主题上有很多结果,但是它们并没有帮助我。
我有一个与user1和user2的好友表。
真正的朋友是当user1是与user2的朋友,而user2是与user1的朋友。
朋友请求是当user1与user2成为朋友时。看起来像这样:
user1 | user2
-------------
1 | 2
2 | 1
1 | 3
3 | 1
1 | 5
该查询看起来如何获得#1的真正朋友?
我试过了,但返回null:
SELECT user2 FROM friends WHERE user1 = 1 AND user2 = 1
查询还将如何查找朋友请求?
最佳答案
一种实现方法是使用JOIN操作:
SELECT f.user2
FROM friends f
JOIN friends r
ON r.user1 = f.user2
AND r.user2 = f.user1
WHERE f.user1 = 1
假定存在两个元组来标识“真实朋友”关系,即
1
和n
之间的真实朋友关系将由表中的两行表示:(1,n)
和(n,1)
。连接条件中的谓词将返回的行限制为具有匹配的“反”元组的行。
注意:JOIN操作通常比等效的
IN (subquery)
或EXISTS (subquery)
模式执行得更好,但是对于小的集合,性能差异可以忽略不计。在更大的集合中,性能差异变得明显。可以使用EXISTS谓词返回等效结果(通常效率较低):
SELECT f.user2
FROM friends f
WHERE f.user1 = 1
AND EXISTS ( SELECT 1
FROM friends r
WHERE r.user1 = f.user2
AND r.user2 = f.user1
)
或IN谓词:
SELECT f.user2
FROM friends f
WHERE f.user1 = 1
AND f.user2 IN ( SELECT r.user1
FROM friends r
WHERE r.user2 = f.user1
)
(如果friends(user1,user2)上没有唯一的约束,那么JOIN可能会返回一些重复的行,而其他查询可能不会返回这些行,但是所有查询都不保证不会返回任何重复项。如果没有唯一的约束,并且您不希望返回任何重复项,则可以在任何这些语句的开头的SELECT之后添加DISTINCT关键字,或者在任何这些语句的末尾添加GROUP BY f.user2。
为了使结果集更具确定性(即每次运行查询都返回相同的结果),您可以添加ORDER BY子句。 (但是对于GROUP BY并不需要,因为MySQL隐式对GROUP BY表达式执行ORDER BY。)
跟进
说明如何将结果与用户表中的名称绑定?谢谢。以及如何获得“不真实”的朋友?
要从用户表中获取名称,我们只需向用户表中添加一个JOIN即可,假设id是主键列,而user1和user2列是用户表的外键...
SELECT f.user2
, u.name
FROM friends f
JOIN user u
ON u.id = f.user2
JOIN friends r
ON r.user1 = f.user2
AND r.user2 = f.user1
WHERE f.user1 = 1
“不真实”的朋友将表示为元组(表中的行)
(1,n)
,它没有对应的逆元组(n,1)
。为了找到这些行,我们使用了一个反联接模式,这是一个OUTER联接(从一侧返回所有行加上任何匹配的行),然后是一个谓词,该谓词排除找到匹配项的行(检查a中是否为NULL)。如果存在匹配项,则保证不为null的列就是我们的操作方式):这将找到没有匹配的
(1,n)
的所有(n,1)
元组:SELECT f.user2
, u.name
FROM friends f
JOIN user u
ON u.id = f.user2
LEFT
JOIN friends r
ON r.user1 = f.user2
AND r.user2 = f.user1
WHERE r.user1 IS NULL
AND f.user1 = 1
我们必须将其翻转以得到另一面,没有匹配的
(n,1)
行的(1,n)
行:SELECT f.user1
FROM friends f
JOIN user u
ON u.id = f.user1
LEFT
JOIN friends r
ON r.user2 = f.user1
AND r.user1 = f.user2
WHERE r.user2 IS NULL
AND f.user2 = 1
关于mysql - 从好友列表中找到真正的 friend ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18342752/