假设你也有一张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 种)来回答这类问题,在这个答案中:如何过滤 SQL 导致具有多通关系的结果其中一些在 MySQL 中不起作用,但很多在 MySQL 中起作用。我希望查询 5 和 6 在 MySQL 中非常有效(比 group by 查询更有效的级别)。
您的情况有所不同,您需要精确的关系划分,而问题/答案是关于(简单)关系划分,所以您可以这样写 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))