我无法找到合适的头衔。
我正在开发一个带有两个表的消息系统,一个包含所有不同的对话(会话中的用户和对话的uid),另一个包含用户之间的消息。
对于每个对话,我正在为对话中的每个用户和对话的uid以及user_id创建一行。在对话中,只有2个用户,但也有更多(3,4,5,6等)
我的SQL语句出了问题,我不知道如何解决。问题是当我们说三个用户之间有一个对话时,之后可以说有两个用户想要在没有第三个用户的情况下私下开始互相交谈。当2个用户与其他用户一起处于对话中时,如何使SQL语句不返回任何内容。这样我就可以在自己的私人conversation_id中添加2个新行。
conversation_list
表如下所示:
|id | user_id| conversation_id|
-----------------------------
| 1 | 1| 1|
| 2 | 3| 1|
| 3 | 1| 2|
| 4 | 2| 2|
| 5 | 4| 2|
现在我的SQL代码是这样的:
SELECT *
FROM conversation_list
WHERE user_id IN (user1_id,user_id2)
GROUP BY conversation_id
HAVING COUNT(*) = 2
答案 0 :(得分:2)
重述问题是否正确:
“当两个用户中的任何一个与任何其他用户进行对话时,如何使SQL语句不返回任何内容?”
...或
“当这些用户不与其他用户进行对话时,如何使SQL语句仅返回行?”
SELECT conversation_id
FROM conversation_list
WHERE user_id IN (5,6)
AND conversation_id NOT IN (
SELECT conversation_id from conversation_list where user_id NOT IN (5,6)
)
GROUP BY conversation_id
HAVING COUNT(*) = :nb_users
如果这些用户不与其他用户进行对话,则只应返回行。
答案 1 :(得分:1)
让我们看看我是否正确理解了您的问题:只有在您列出了参与该对话的所有conversation_id
时,您才想返回user_id
?
如果是这种情况,请查看我对this question的回答。您可以将对话视为命名的参与者集合,因此conversation_id
是集合的名称,user_id
是该集合的项目。答案有3种不同的方法,包括解释。
适应您桌面的最后一个版本大致如下:
SELECT totals.conversation_id
FROM (
SELECT conversation_id, COUNT(*) count
FROM conversation_list
GROUP BY conversation_id
) totals
INNER JOIN (
SELECT conversation_id, COUNT(*) count
FROM conversation_list
WHERE user_id IN (6, 5)
GROUP BY conversation_id
) matches
ON (totals.conversation_id = matches.conversation_id)
WHERE totals.count = 2 AND matches.count = 2;
其中6和5是user_id
s,2是user_id
s的数量。
第一个子查询查找每个对话中的用户总数,第二个子查询查找每个对话中匹配用户的数量。当matches.count
为2时,会话中包含我们正在查找的所有用户,如果totals.count
也是2,则会话中没有任何额外用户。