简体   繁体   English

MySQL-仅在列包含特定值的情况下选择其他内容

[英]MySQL - Select something ONLY where columns contain specific values, and nothing else

I have a messages_users table that contains users participating to a conversation : 我有一个messages_users表,其中包含参与对话的用户:

conversationId | userId

Since the purpose is that multiple users can get in a conversation, one row equals one user. 由于目的是多个用户可以进行对话,因此一行等于一个用户。

There are two types of conversations : conversation with friend, and grouped conversation with multiple users. 对话有两种类型:与朋友对话和与多个用户的分组对话。 What distincts them is only the number of people in it. 他们与众不同的只是其中的人数。

2 users = conversation with friend 2位用户=与朋友交谈

3 or more = grouped conversation 3个或更多=分组的对话

I want to allow users to open a conversation with their friends from their ids (here, 1 and 2). 我想允许用户通过其ID(此处为1和2)与他们的朋友打开对话。 So, I need to make a SQL statement that will retrive a conversation id ONLY where those two users are in. 因此,我需要制作一条SQL语句,仅检索这两个用户所在的会话ID。

If I do this, I'll get every conversations that those two users are in (if there are grouped conversations with them, for example) 如果这样做,我将获得这两个用户所在的所有对话(例如,如果有与他们分组的对话)

SELECT convId FROM messages_users WHERE userId IN (1,2)

I tried this but it won't work : 我尝试了这个,但是不起作用:

SELECT convId FROM messages_users WHERE userId IN (1,2) HAVING COUNT(userId) = 2

Also tried this, but still it will get me every conversations they are in : 也尝试过此方法,但仍然可以使我与他们进行的每一次对话:

SELECT convId FROM messages_users a INNER JOIN messages_users b ON a.convId = b.convId WHERE a.userId = 1 AND b.userId = 2

The condition that you want is: 您想要的条件是:

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;

You can't filter before the GROUP BY because then you would miss counting user "3" if in the conversation. 您不能 GROUP BY 之前进行过滤因为如果在对话中,那么您将错过对用户“ 3”的计数。 The third condition prevents "3" from participating. 第三个条件阻止“ 3”参与。

In MySQL, this can be simplified to: 在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;

We can try using a self-join operation with an EXISTS clause: 我们可以尝试使用带有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));

Here is a link to a demo showing that the above logic works: 这是一个演示的链接,显示了以上逻辑的工作原理:

Demo 演示版

For every " conversation with friend " there must be only 2 rows with the same convId : 对于每次“ 与朋友的交谈 ”,必须只有2行具有相同的convId

SELECT convId
FROM messages_users 
GROUP BY convId
HAVING COUNT(userId) = 2;

If you want the " conversations with friend " for users 1 and 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); 

See demo 观看演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM