在 mysql table 上结交共同好友

Get Mutual friends on mysql table

我有 Userstatuslink_user_friend

用户保存用户详细信息的位置 status 保存好友请求的状态 link_user_friend持有用户和好友

的link

table如下

user
+--------+--------+---------+
| fname  | lname  | user_id |
+--------+--------+---------+
| Fone   | Lone!  | ID_1    |
| Ftwo   | Ltwo!  | ID_2    |
| Fthree | Lthree!| ID_3    |
| Ffour  | Lfour! | ID_4    |
| Ffive  | Lfive! | ID_5    |
| Fsix   | Lsix!  | ID_6    |
| Fseven | Lseven!| ID_7    |
| Feight | Leight!| ID_8    |
| Fnine  | Lnine! | ID_9    |
| Ften   | Lten!  | ID_10   |
| Fele   | Lele!  | ID_11   |
| Ftwl   | Ltwl!  | ID_12   |
+---------------------------+

Status        
+-----+-------------------------+
| _id | name                    |
+-----+-------------------------+
|   1 | Friend Request Sent     |
|   2 | Friend Request Rejected |
|   3 | Friends                 |
|   4 | Block                   |
+-----+-------------------------+    

link_user_friend
+-----+---------+------------+--------+
| _id | user_id | friend_id  | status |
+-----+---------+------------+--------+
| a1  | ID_1    | ID_2       |      1 |
| a2  | ID_1    | ID_3       |      2 |
| a3  | ID_1    | ID_4       |      3 |
| a4  | ID_1    | ID_5       |      4 |
| a5  | ID_1    | ID_6       |      3 |
| a6  | ID_1    | ID_7       |      3 |
| a7  | ID_2    | ID_3       |      2 |
| a8  | ID_2    | ID_4       |      1 |
| a9  | ID_2    | ID_5       |      1 |
| b1  | ID_2    | ID_6       |      3 |
| b2  | ID_2    | ID_7       |      2 |
| b3  | ID_2    | ID_8       |      4 |
| b4  | ID_2    | ID_9       |      1 |
| b5  | ID_2    | ID_10      |      2 |
| b6  | ID_2    | ID_11      |      3 |
| b7  | ID_2    | ID_12      |      3 |
| b8  | ID_3    | ID_4       |      3 |
| b9  | ID_3    | ID_5       |      3 |
| c1  | ID_3    | ID_6       |      3 |
| c2  | ID_3    | ID_7       |      3 |
| c3  | ID_3    | ID_8       |      1 |
| c4  | ID_3    | ID_9       |      3 |
| c5  | ID_3    | ID_10      |      3 |
| c6  | ID_3    | ID_11      |      2 |
| c7  | ID_3    | ID_12      |      3 |
| c8  | ID_4    | ID_5       |      3 |
| c9  | ID_4    | ID_6       |      3 |
| d1  | ID_4    | ID_7       |      3 |
| d2  | ID_4    | ID_8       |      3 |
| d3  | ID_4    | ID_9       |      3 |
| d4  | ID_4    | ID_10      |      3 |
| d5  | ID_4    | ID_11      |      3 |
| d6  | ID_4    | ID_12      |      3 |
| d7  | ID_5    | ID_6       |      3 |
| d8  | ID_5    | ID_7       |      3 |
| d9  | ID_5    | ID_8       |      1 |
| e1  | ID_5    | ID_9       |      3 |
| e2  | ID_5    | ID_10      |      3 |
| e3  | ID_5    | ID_11      |      3 |
| e4  | ID_5    | ID_12      |      3 |
| e5  | ID_6    | ID_7       |      3 |
| e6  | ID_6    | ID_8       |      3 |
| e7  | ID_6    | ID_9       |      1 |
| e8  | ID_6    | ID_10      |      3 |
| e9  | ID_6    | ID_11      |      2 |
| f1  | ID_6    | ID_12      |      3 |
| f2  | ID_7    | ID_8       |      3 |
| f3  | ID_7    | ID_9       |      3 |
| f4  | ID_7    | ID_10      |      3 |
| f5  | ID_7    | ID_11      |      3 |
| f6  | ID_7    | ID_12      |      3 |
+-----+---------+------------+--------+

我想获取用户的朋友列表,他们有共同的朋友 现在,我可以获取 ID 为 ID_7

的用户的前好友列表
select *
from
((select u.fname fname, u.lname lname, u.user_id, f.status 
from link_user_friend f, user u
where u.user_id = f.friend_id
and f.user_id = 'ID_7'
and f.status = 3)
UNION
(select u.fname, u.lname, u.user_id, f.status 
from link_user_friend f, user u
where u.user_id = f.user_id
and f.friend_id = 'ID_7'
and f.status = 3)) as t order by user_id

给我结果

+--------+---------+---------+--------+
| fname  | lname   | user_id | status |
+--------+---------+---------+--------+
| Fone   | Lone!   | ID_1    |      3 |
| Ften   | Lten!   | ID_10   |      3 |
| Fele   | Lele!   | ID_11   |      3 |
| Ftwl   | Ltwl!   | ID_12   |      3 |
| Fthree | Lthree! | ID_3    |      3 |
| Ffour  | Lfour!  | ID_4    |      3 |
| Ffive  | Lfive!  | ID_5    |      3 |
| Fsix   | Lsix!   | ID_6    |      3 |
| Feight | Leight! | ID_8    |      3 |
| Fnine  | Lnine!  | ID_9    |      3 |
+--------+---------+---------+--------+

同样的方法

select *
from
((select u.fname fname, u.lname lname, u.user_id, f.status 
from link_user_friend f, user u
where u.user_id = f.friend_id
and f.user_id = 'ID_1'
and f.status = 3)
UNION
(select u.fname, u.lname, u.user_id, f.status 
from link_user_friend f, user u
where u.user_id = f.user_id
and f.friend_id = 'ID_1'
and f.status = 3)) as t order by user_id

我得到结果

+--------+---------+---------+--------+
| fname  | lname   | user_id | status |
+--------+---------+---------+--------+
| Ffour  | Lfour!  | ID_4    |      3 |
| Fsix   | Lsix!   | ID_6    |      3 |
| Fseven | Lseven! | ID_7    |      3 |
+--------+---------+---------+--------+

所以当我们比较上面的 table 用户 ID_4, ID_6ID_7ID_1 的普通朋友时,那么共同的朋友数是 2

其他用户也一样 我需要共同的朋友算作多一栏。喜欢

+--------+---------+---------+--------+----------------+
| fname  | lname   | user_id | status | Mutual Friends |
+--------+---------+---------+--------+----------------+
| Fone   | Lone!   | ID_1    |      3 |      2         |
| Ften   | Lten!   | ID_10   |      3 |      .         |
| Fele   | Lele!   | ID_11   |      3 |      .         |
| Ftwl   | Ltwl!   | ID_12   |      3 |      .         |
| Fthree | Lthree! | ID_3    |      3 |      .         |
| Ffour  | Lfour!  | ID_4    |      3 |      .         |
| Ffive  | Lfive!  | ID_5    |      3 |      .         |
| Fsix   | Lsix!   | ID_6    |      3 |      .         |
| Feight | Leight! | ID_8    |      3 |      .         |
| Fnine  | Lnine!  | ID_9    |      3 |      .         |
+--------+---------+---------+--------+----------------+
  1. 我不明白如何统计共同好友数。我想迭代每个条目并获得共同的朋友数,但它有性能问题。有没有办法只进入一个查询

  2. 我想要一个任意随机用户的共同好友列表 例如,如果用户搜索某个名称。我会将该名称与用户 table 匹配,并且我有一组 user_id。对于那些 user_id 我想要共同的朋友数。

请有人帮助我

我已附加插入和创建 sql

CREATE TABLE `friend_status` (
  `_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`_id`));

INSERT INTO `friend_status` (`name`) VALUES ('Friend Request Sent');
INSERT INTO `friend_status` (`name`) VALUES ('Friend Request Rejected');
INSERT INTO `friend_status` (`name`) VALUES ('Friends');
INSERT INTO `friend_status` (`name`) VALUES ('Block');

CREATE TABLE `user` (
  `user_id` VARCHAR(50) NOT NULL,
  `fname` VARCHAR(45) NULL,
  `lname` VARCHAR(45) NULL,
  PRIMARY KEY (`user_id`));

CREATE TABLE `link_user_friend` (
  `_id` VARCHAR(50) NOT NULL,
  `user_id` VARCHAR(50) NOT NULL,
  `friend_id` VARCHAR(50) NOT NULL,
  `status` INT NOT NULL DEFAULT 1,
  PRIMARY KEY (`_id`),
  CONSTRAINT `status`
    FOREIGN KEY (`status`)
    REFERENCES `friend_status` (`_id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE);

Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Ftwo','Ltwo!','ID_2');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Fthree','Lthree!','ID_3');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Ffour','Lfour! ','ID_4');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Ffive','Lfive! ','ID_5');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Fsix','Lsix!  ','ID_6');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Fseven','Lseven!','ID_7');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Feight','Leight!','ID_8');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Fnine','Lnine! ','ID_9');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Ften','Lten!  ','ID_10');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Fele','Lele!  ','ID_11');
Insert into user (`account_type`,`fname`, `lname`, `user_id`) values('1','Ftwl','Ltwl!  ','ID_12');


insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa1','ID_1','ID_2','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa2','ID_1','ID_3','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa3','ID_1','ID_4','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa4','ID_1','ID_5','4');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa5','ID_1','ID_6','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa6','ID_1','ID_7','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa7','ID_2','ID_3','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa8','ID_2','ID_4','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fa9','ID_2','ID_5','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb1','ID_2','ID_6','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb2','ID_2','ID_7','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb3','ID_2','ID_8','4');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb4','ID_2','ID_9','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb5','ID_2','ID_10','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb6','ID_2','ID_11','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb7','ID_2','ID_12','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb8','ID_3','ID_4','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fb9','ID_3','ID_5','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc1','ID_3','ID_6','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc2','ID_3','ID_7','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc3','ID_3','ID_8','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc4','ID_3','ID_9','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc5','ID_3','ID_10','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc6','ID_3','ID_11','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc7','ID_3','ID_12','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc8','ID_4','ID_5','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fc9','ID_4','ID_6','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd1','ID_4','ID_7','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd2','ID_4','ID_8','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd3','ID_4','ID_9','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd4','ID_4','ID_10','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd5','ID_4','ID_11','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd6','ID_4','ID_12','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd7','ID_5','ID_6','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd8','ID_5','ID_7','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fd9','ID_5','ID_8','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe1','ID_5','ID_9','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe2','ID_5','ID_10','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe3','ID_5','ID_11','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe4','ID_5','ID_12','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe5','ID_6','ID_7','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe6','ID_6','ID_8','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe7','ID_6','ID_9','1');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe8','ID_6','ID_10','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('fe9','ID_6','ID_11','2');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff1','ID_6','ID_12','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff2','ID_7','ID_8','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff3','ID_7','ID_9','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff4','ID_7','ID_10','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff5','ID_7','ID_11','3');
insert into link_user_friend (`_id`,`user_id`,`friend_id`,`status`) values('ff6','ID_7','ID_12','3');

不幸的是,为了澄清一些事情,我无法在聊天中联系到。 所以我为你写了一个几乎可以做所有事情的查询(我希望)。 查询末尾有 2 行,您可以在其中更改它的功能。

首先是 WHERE u1.user_id ='ID_4' AND u2.user_id ='ID_6' 行。如果删除它,查询将向彼此输出所有用户,或者您只删除第二个用户 (u2),您会从 user1 获得所有共同用户的列表。

其次,您可以删除或更改 HAVING sum_of_mutual_friends > 2 行以更改报告用户的计数

SELECT
  u1.user_id AS user_1,
  u2.user_id AS user_2,
  GROUP_CONCAT(IF( f.user_id = u1.user_id, f.friend_id, f.user_id) SEPARATOR ', ') AS mutual_friends,
  sum(1) sum_of_mutual_friends
FROM USER u1
LEFT JOIN USER u2 ON u1.user_id <> u2.user_id AND u1.user_id < u2.user_id 
LEFT JOIN  link_user_friend f ON f.status =3 AND ( f.user_id = u1.user_id OR f.friend_id = u1.user_id ) AND f.user_id <> u2.user_id
INNER JOIN link_user_friend m ON
  (
    (m.user_id = IF( f.user_id = u1.user_id, f.friend_id, f.user_id)  AND m.friend_id = u2.user_id )
  OR
  (
    m.friend_id = IF( f.user_id = u1.user_id, f.friend_id, f.user_id) AND m.user_id = u2.user_id    )
  )
  AND
    m.status = 3
WHERE u1.user_id ='ID_4' AND u2.user_id ='ID_6'
GROUP BY u1.user_id,u2.user_id
HAVING sum_of_mutual_friends > 2
;

结果:

+--------+--------+--------------------------------------------+-----------------------+
| user_1 | user_2 | mutual_friends                             | sum_of_mutual_friends |
+--------+--------+--------------------------------------------+-----------------------+
| ID_4   | ID_6   | ID_1, ID_3, ID_5, ID_7, ID_8, ID_10, ID_12 |                     7 |
+--------+--------+--------------------------------------------+-----------------------+

并且没有 where

+--------+--------+---------------------------------------------------------+-----------------------+
| user_1 | user_2 | mutual_friends                                          | sum_of_mutual_friends |
+--------+--------+---------------------------------------------------------+-----------------------+
| ID_1   | ID_10  | ID_4, ID_7, ID_6                                        |                     3 |
| ID_1   | ID_12  | ID_7, ID_6, ID_4                                        |                     3 |
| ID_1   | ID_3   | ID_4, ID_6, ID_7                                        |                     3 |
| ID_1   | ID_5   | ID_7, ID_6, ID_4                                        |                     3 |
| ID_1   | ID_8   | ID_7, ID_6, ID_4                                        |                     3 |
| ID_10  | ID_11  | ID_4, ID_7, ID_5                                        |                     3 |
| ID_10  | ID_12  | ID_5, ID_7, ID_3, ID_4, ID_6                            |                     5 |
| ID_10  | ID_3   | ID_5, ID_6, ID_7, ID_4                                  |                     4 |
| ID_10  | ID_4   | ID_6, ID_7, ID_5, ID_3                                  |                     4 |
| ID_10  | ID_5   | ID_4, ID_7, ID_3, ID_6                                  |                     4 |
| ID_10  | ID_6   | ID_7, ID_5, ID_3, ID_4                                  |                     4 |
| ID_10  | ID_7   | ID_5, ID_4, ID_6, ID_3                                  |                     4 |
| ID_10  | ID_8   | ID_6, ID_4, ID_7                                        |                     3 |
| ID_10  | ID_9   | ID_7, ID_5, ID_4, ID_3                                  |                     4 |
| ID_11  | ID_12  | ID_4, ID_2, ID_5, ID_7                                  |                     4 |
| ID_11  | ID_3   | ID_7, ID_4, ID_5                                        |                     3 |
| ID_11  | ID_6   | ID_7, ID_2, ID_5, ID_4                                  |                     4 |
| ID_11  | ID_9   | ID_7, ID_5, ID_4                                        |                     3 |
| ID_12  | ID_3   | ID_5, ID_6, ID_7, ID_4                                  |                     4 |
| ID_12  | ID_4   | ID_7, ID_5, ID_3, ID_6                                  |                     4 |
| ID_12  | ID_5   | ID_7, ID_3, ID_6, ID_4                                  |                     4 |
| ID_12  | ID_6   | ID_5, ID_4, ID_3, ID_7, ID_2                            |                     5 |
| ID_12  | ID_7   | ID_6, ID_3, ID_5, ID_4                                  |                     4 |
| ID_12  | ID_8   | ID_4, ID_7, ID_6                                        |                     3 |
| ID_12  | ID_9   | ID_5, ID_4, ID_3, ID_7                                  |                     4 |
| ID_2   | ID_4   | ID_11, ID_6, ID_12                                      |                     3 |
| ID_2   | ID_5   | ID_11, ID_6, ID_12                                      |                     3 |
| ID_2   | ID_7   | ID_12, ID_6, ID_11                                      |                     3 |
| ID_3   | ID_4   | ID_6, ID_12, ID_5, ID_9, ID_10, ID_7                    |                     6 |
| ID_3   | ID_5   | ID_7, ID_6, ID_12, ID_9, ID_4, ID_10                    |                     6 |
| ID_3   | ID_6   | ID_12, ID_4, ID_5, ID_10, ID_7                          |                     5 |
| ID_3   | ID_7   | ID_12, ID_6, ID_4, ID_5, ID_10, ID_9                    |                     6 |
| ID_3   | ID_8   | ID_6, ID_7, ID_4                                        |                     3 |
| ID_3   | ID_9   | ID_4, ID_7, ID_5                                        |                     3 |
| ID_4   | ID_5   | ID_9, ID_11, ID_12, ID_7, ID_10, ID_6, ID_3             |                     7 |
| ID_4   | ID_6   | ID_3, ID_1, ID_12, ID_10, ID_7, ID_8, ID_5              |                     7 |
| ID_4   | ID_7   | ID_11, ID_10, ID_9, ID_3, ID_6, ID_12, ID_5, ID_8, ID_1 |                     9 |
| ID_4   | ID_9   | ID_5, ID_7, ID_3                                        |                     3 |
| ID_5   | ID_6   | ID_3, ID_12, ID_4, ID_7, ID_10                          |                     5 |
| ID_5   | ID_7   | ID_6, ID_3, ID_12, ID_4, ID_11, ID_9, ID_10             |                     7 |
| ID_5   | ID_8   | ID_6, ID_4, ID_7                                        |                     3 |
| ID_5   | ID_9   | ID_7, ID_3, ID_4                                        |                     3 |
| ID_6   | ID_7   | ID_3, ID_8, ID_12, ID_5, ID_4, ID_1, ID_10              |                     7 |
| ID_6   | ID_9   | ID_3, ID_4, ID_7, ID_5                                  |                     4 |
| ID_7   | ID_9   | ID_3, ID_4, ID_5                                        |                     3 |
+--------+--------+---------------------------------------------------------+-----------------------+
45 rows in set (0.01 sec)

注意

如果 user_lists.

很大,则必须设置 GROUP_CONCAT 的大小

如果这是您要找的,请现在告诉我。