我有两个简单的 MySQL 表:用户和关系。
关系表:
user_id int(10) unsigned NO PRI
friend_id int(10) unsigned NO PRI
(部分)用户表:
id int(10) unsigned NO PRI
username varchar(128) NO
我使用此查询选择 friend 的 friend :
SELECT f2.friend_id, u.username
FROM relations f1
JOIN relations f2 ON f1.friend_id=f2.user_id
LEFT JOIN user u ON u.id = f2.friend_id
WHERE f2.friend_id NOT IN (select friend_id from relations where user_id=@user_id) AND f1.user_id= 2 AND f2.friend_id!= 2
但我还需要得到建议的 friend ...(组中认识 2 个或更多直接 friend 的人),我对此有疑问。什么是获得推荐 friend 的好方法(查询,或者我应该用 PHP 来做?)?
最佳答案
考虑以下……这个例子假设互惠是通过为每个友谊插入两行来建立的。但是,为简单起见,以下示例不会检查友谊是否是相互的!
DROP TABLE IF EXISTS friends;
CREATE TABLE friends
(initiator VARCHAR(12) NOT NULL
,reciprocator VARCHAR(12) NOT NULL
,PRIMARY KEY (initiator,reciprocator)
);
INSERT INTO friends VALUES
('Adam','Ed'),
('Ed','Adam'),
('Adam','Ben'),
('Ben','Adam'),
('Adam','Charlie'),
('Charlie','Adam'),
('Adam','Dan'),
('Dan','Adam'),
('Ed','Ben'),
('Ben','Ed'),
('Ben','Charlie'),
('Charlie','Ben'),
('Charlie','Dan'),
('Dan','Charlie'),
('Dan','Fred'),
('Fred','Dan'),
('Adam','Fred'),
('Fred','Adam');
要获得 Ben 所有“ friend 的 friend ”的列表,我们可以这样做...
SELECT y.reciprocator
FROM friends x
JOIN friends y
ON y.initiator = x.reciprocator
AND y.reciprocator <> x.initiator
LEFT
JOIN friends z
ON z.reciprocator = y.reciprocator
AND z.initiator = x.initiator
WHERE x.initiator = 'Ben'
AND z.initiator IS NULL;
+--------------+
| reciprocator |
+--------------+
| Dan |
| Fred |
| Dan |
+--------------+
如您所见,因为 Dan 与 Adam 和 Charlie(都是 Ben 的 friend )都是 friend ,所以他的名字出现了两次。
因此,要获得 DISTINCT friend 的 friend 列表,只需包含 DISTINCT 运算符即可。
同样,要获得对 Ben 陌生但至少是 Ben 的两个 friend 的 friend 的列表,我们可以这样做...
SELECT y.reciprocator
FROM friends x
LEFT
JOIN friends y
ON y.initiator = x.reciprocator
AND y.reciprocator <> x.initiator
LEFT
JOIN friends z
ON z.reciprocator = y.reciprocator
AND z.initiator = x.initiator
WHERE x.initiator = 'Ben'
AND z.initiator IS NULL
GROUP
BY y.reciprocator
HAVING COUNT(*) >= 2;
+--------------+
| reciprocator |
+--------------+
| Dan |
+--------------+
处理这个问题的互惠方面可能有几种方法,就像处理互惠本身有几种方法一样。
一种方法是用一个简单的子查询替换上面每次出现的 friends
表,例如
SELECT y.reciprocator
FROM (SELECT a.* FROM friends a JOIN friends b ON b.reciprocator = a.initiator AND b.initiator = a.reciprocator) x
LEFT
JOIN (SELECT a.* FROM friends a JOIN friends b ON b.reciprocator = a.initiator AND b.initiator = a.reciprocator) y
ON y.initiator = x.reciprocator
AND y.reciprocator <> x.initiator
LEFT
JOIN (SELECT a.* FROM friends a JOIN friends b ON b.reciprocator = a.initiator AND b.initiator = a.reciprocator) z
ON z.reciprocator = y.reciprocator
AND z.initiator = x.initiator
WHERE x.initiator = 'Ben'
AND z.initiator IS NULL
GROUP
BY y.reciprocator
HAVING COUNT(*) >= 2;
关于mysql - 社交网络 - 推荐的 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20187230/