根据相互喜欢加入 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 |
+--------------------------+
好的,所以我有两个 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 |
+--------------------------+