I have the following tables.
conversations
| id |
------
1
and
conversationMembers
| id | conversationId | userId | email
---------------------------------------
1 1 2 null
2 1 null test@test.com
3 1 7 null
Basically, I'm trying to construct a MySQL query that returns a row from the conversations table by an exact match of conversationMembers.
So, here's some examples of expected returns.
Let's say we want aa conversation id for a conversation between the exact following members: userId 2, userId 7, email test@test.com - This would see that in the conversationMembers table there's rows with the same conversation id and the exact match across all members of that conversation id that we're searching for. It would return conversations row with id 1.
Here's another example. We want a conversation id for a conversation between userId 2 and userId 7. This would see that there's not a conversation exclusively between userId 2 and userId 7, so it would not return anything.
And a final example. Let's say we want userId 7 and userId 9, this would also see there's no exclusive conversation between these 2 user id's and would return nothing.
What's the best way to go about doing it? I've played with subqueries but everything I've come up with doesn't seem to be able to handle the exact matching situation - I was having issues with selecting conversations for example - on userId 2 and 7 only (which should return nothing) and was getting conversationId 1 back, even though I didn't specify I wanted a conversation with test@test.com email as a part of it. I should only have gotten conversationId 1 back for if I searched on an exact match of all members in for conversationId.
One method is to use group by
and having
. This is nice because it is flexible with regards to what can be expressed. So, your first example is:
select conversionid
from conversationMembers
group by conversionid
having sum(userId = 2) > 0 and
sum(userId = 7) > 0 and
sum(email = 'test@test.com') > 0;
The condition being summed counts the number of members that match. The > 0
means there is at least one. For the second condition, the clause would be:
having sum(userId = 2) > 0 and
sum(userId = 7) > 0 and
sum(userId not in (2, 7)) = 0;
or alternatively:
select conversionid
from conversationMembers
group by conversionid
having sum(userId = 2) > 0 and
sum(userId = 7) > 0 and
count(distinct userId) = 2;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.