根据相互喜欢加入 MySQL 中的两个表

Joining two tables in MySQL based upon mutual likes

好的,所以我有两个 MySQL table;一个叫做 users,另一个叫做 likes

用户table

id         name
-----      ------
1          Mark
2          John
3          Paul
4          Dave
5          Chris

赞table

liked_by    liked  match_id
-----      ------    --------
  1          2         1
  2          1         2
  1          3         3
  2          3         4
  1          5         5
  5          1         6

我能够按如下方式成功加入两个 table

SELECT users.id, likes.*
FROM users
JOIN likes
ON users.id = likes.liked

但是,我不确定如何设置 WHERE 子句的格式,以便 return 编辑以下行。

name      liked_by    liked     match_id
------    -------     --------  -------- 
Mark         1           3         3
John         2           3         4  

如您所见,我正在尝试 return Mark 和 John 都喜欢同一用户的行。在本例中,它是用户 3,即 Paul。我尝试将以下子句添加到查询中,但它显然不起作用。

WHERE (likes.liked_by = '1' OR likes.liked_by = '2')

找到有多行的喜欢的(likees?)。否则它只是一个内部连接:

select *
from Likes as l inner join Users as u on u.id = l.liked_by
where liked in (
    select liked
    from Likes
    --where liked_by in (:userid1, :userid2) /* optional: specific pair of users */
    --where liked (:userid1, :userid2) /* optional: specific likee */
    group by liked
    having count(*) > 1
)

我经常听到 in 子查询在 MySQL 上优化不佳。由于分组将保证一对一的关系,因此很容易将其转换为派生 table/inline view/nested 视图或任何你们称之为的内部联接。

您需要加入 likes table 自身以获得喜欢特定用户的成对用户列表。查询相当简单。

测试数据:

CREATE TABLE users (id INT, name VARCHAR(100));
INSERT INTO users(id, name) VALUES (1,'Mark'), (2,'John'), (3,'Paul'), (4,'Dave'), (5,'Chris');

-- Note: I assumed that match_id is a primary key
CREATE TABLE likes (match_id INT PRIMARY KEY AUTO_INCREMENT, liked_by INT, liked INT);
INSERT INTO likes(liked_by, liked) VALUES (1,2), (2,1), (1,3), (2,3), (1,5), (5,1);

实际查询:

SELECT CONCAT(user1.name, ' and ', user2.name, ' like ', user3.name) AS `Readable result`
-- join the likes table with itself where two users like the same user
FROM likes AS like1
INNER JOIN likes AS like2 ON like1.liked = like2.liked AND
                             like1.match_id < like2.match_id
-- join the result with user table three times to obtain names of all users involved
INNER JOIN users AS user1 ON like1.liked_by = user1.id
INNER JOIN users AS user2 ON like2.liked_by = user2.id
INNER JOIN users AS user3 ON like1.liked = user3.id

结果:

+--------------------------+
| Readable result          |
+--------------------------+
| Mark and John like Paul  |
| John and Chris like Mark |
+--------------------------+