当行数多于IN值时,MYSQL返回null

时间:2012-06-07 19:27:59

标签: mysql sql messaging where-in

我无法找到合适的头衔。

我正在开发一个带有两个表的消息系统,一个包含所有不同的对话(会话中的用户和对话的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 

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,则会话中没有任何额外用户。