假如你有一个users
表,以及:
SELECT id
FROM conversations AS c
WHERE NOT EXISTS
(SELECT *
FROM users AS u
WHERE u.id IN (1, 2, 3, 4)
AND NOT EXISTS
(SELECT *
FROM conversations_users AS cu
WHERE cu.user = u.id
AND cu.conversation = c.id
)
)
AND NOT EXISTS
(SELECT *
FROM conversations_users AS co -- and only them
WHERE co.conversation = c.id
AND co.user NOT IN (1, 2, 3, 4)
) ;
如果没有users
表或者你不喜欢使用它(可以理解,但无论如何),您可以替换此部分:
WHERE NOT EXISTS
(SELECT *
FROM users AS u
WHERE u.id IN (1, 2, 3, 4)
AND NOT EXISTS
用:
WHERE NOT EXISTS
(SELECT *
FROM (SELECT 1 AS id UNION SELECT 2 UNION
SELECT 3 UNION SELECT 4) AS u
WHERE NOT EXISTS
上面的查询,而被一般不会出现在MySQL非常有效的(怪双嵌套和幼稚优化器)。 GROUP BY/COUNT
方式可能更高效 - 但请使用您的数据进行测试。你也可以找到更多的方法(超过10)来回答这种问题,在这个答案:How to filter SQL results in a has-many-through relation其中一些不在MySQL中工作,但很多都做。我期望查询5和6在MySQL中非常高效(比查询组更有效)。
你的情况有区别,你想确切的关系划分,而这个问题/答案是约(简单)的关系划分,所以你可以写5是这样的:
SELECT id
FROM conversations AS c
WHERE EXISTS (SELECT * FROM conversations_users AS cu
WHERE cu.conversation = c.id AND cu.user = 1)
AND EXISTS (SELECT * FROM conversations_users AS cu
WHERE cu.conversation = c.id AND cu.user = 2)
AND EXISTS (SELECT * FROM conversations_users AS cu
WHERE cu.conversation = c.id AND cu.user = 3)
AND EXISTS (SELECT * FROM conversations_users AS cu
WHERE cu.conversation = c.id AND cu.user = 4)
AND NOT EXISTS (SELECT * FROM conversations_users AS cu
WHERE cu.conversation = c.id AND cu.user NOT IN (1,2,3,4))
这将是我们更容易帮助你,如果你设置了[SQL小提琴(http://sqlfiddle.com/) – 2013-04-30 13:22:16
由于用户5的存在,我认为你不要求所有四个用户(1,2,3,4)都在您正在寻找的对话中,但是您正在寻找包含(1,2,3,4)用户的任何组合的任何对话。你能澄清这一点吗? – gillyspy 2013-04-30 14:27:42