我有一个messages_users表,其中包含参与对话的用户:
conversationId | userId
由于目的是使多个用户可以进行对话,所以一行等于一个用户。
有两种类型的对话:与朋友的对话和与多个用户的分组对话。他们与众不同的只是其中的人数。
2个用户=与朋友交谈
3个或更多=分组的对话
我想允许用户使用其ID(此处为1和2)与他们的朋友打开对话。因此,我需要制作一条SQL语句,仅检索这两个用户所在的会话ID。
如果执行此操作,我将获得这两个用户所在的所有对话(例如,如果与他们进行分组对话)
SELECT convId FROM messages_users WHERE userId IN (1,2)
我试过了,但是没用:
SELECT convId FROM messages_users WHERE userId IN (1,2) HAVING COUNT(userId) = 2
也尝试过此方法,但仍然可以让我进行他们所处的所有对话:
SELECT convId FROM messages_users a INNER JOIN messages_users b ON a.convId = b.convId WHERE a.userId = 1 AND b.userId = 2
答案 0 :(得分:3)
您想要的条件是:
SELECT mu.convId
FROM messages_users mu
GROUP BY mu.convId
HAVING SUM(CASE WHEN mu.userId = 1 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN mu.userId = 2 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN mu.userId NOT IN (1, 2) THEN 1 ELSE 0 END) = 0;
您不能在GROUP BY
之前过滤 ,因为如果在对话中,您将错过对用户“ 3”的计数。第三个条件阻止“ 3”参与。
在MySQL中,可以简化为:
SELECT mu.convId
FROM messages_users mu
GROUP BY mu.convId
HAVING SUM( mu.userId = 1 ) > 0 AND
SUM( mu.userId = 2 ) > 0 AND
SUM( mu.userId NOT IN (1, 2) ) = 0;
答案 1 :(得分:2)
我们可以尝试使用带有EXISTS
子句的自联接操作:
SELECT DISTINCT mu1.convId
FROM messages_users mu1
INNER JOIN messages_users mu2
ON mu1.convId = mu2.convId
WHERE
(mu1.userId = 1 AND mu2.userId = 2) AND
NOT EXISTS (SELECT 1 FROM messages_users mu
WHERE mu.convId = mu1.convId AND userID NOT IN (1, 2));
这里是演示的链接,显示上述逻辑有效:
答案 2 :(得分:1)
对于每次“ 与朋友的对话”,必须只有两行具有相同的convId
:
SELECT convId
FROM messages_users
GROUP BY convId
HAVING COUNT(userId) = 2;
如果您要与用户1和2进行“ 与朋友的对话”
SELECT DISTINCT convId FROM messages_users
WHERE
(userId IN (1, 2))
AND
convId IN
(SELECT convId
FROM messages_users
GROUP BY convId
HAVING COUNT(userId) = 2);
请参见demo