我有一个表,有两列,user
和 group
。这是一个多对多的关系,所以我们可能有...
group | user
1 | 1
1 | 2
1 | 3
2 | 1
2 | 3
3 | 1
3 | 4
4 | 2
4 | 3
...等等。
我需要获取包含特定用户 ID 的所有组中的用户列表。所以对于上面的内容,如果我给它用户 ID 3,它会首先获取该用户的所有组(在本例中为 1、2 和 4),然后返回这些组的所有用户(在本例中为 1 、2 和 3)。现在,这是通过两个嵌套选择来完成的:
SELECT * FROM other_table
WHERE user_id IN (
SELECT user_id FROM table WHERE group_id IN (
SELECT group_id FROM table WHERE user_id = 3
)
)
事实证明这是非常低效的。我在这里明显遗漏了什么吗?
即使我自己运行查询,它的运行效率也很低:
SELECT user_id FROM table WHERE group_id IN (
SELECT group_id FROM table WHERE user_id = 3
)
编辑:这是表格的 CREATE TABLE
。
CREATE TABLE `user_groups` (
`user_id` bigint(12) unsigned NOT NULL,
`group_id` bigint(12) unsigned NOT NULL,
PRIMARY KEY (`user_id`,`group_id`),
KEY `user_id` (`user_id`),
KEY `group_id` (`group_id`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1
编辑:并在下面的答案中解释查询会发生什么:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | t1 | ref | PRIMARY,user_id,group_id | PRIMARY | 8 | const | 839 | Using index
1 | SIMPLE | t2 | ref | PRIMARY,user_id,group_id | group_id | 8 | t1.group_id | 2331 |
1 | SIMPLE | users | eq_ref | PRIMARY | PRIMARY | 8 | t2.user_id | 1 |
最佳答案
只需使用自连接:
SELECT other_table.*
FROM `table` t1
JOIN `table` t2 USING (group_id)
JOIN other_table ON other_table.user_id = t2.user_id
WHERE t1.user_id = 3
关于mysql - 如何最好地查询 "all Y for each X that has a matching Y"的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10917838/