Dette er et tilfælde af relationel opdeling . Vi har samlet et arsenal af teknikker under dette relaterede spørgsmål:
Den særlige vanskelighed er at udelukke yderligere brugere. Der er grundlæggende 4 teknikker.
Jeg foreslår LEFT JOIN
/ IS NULL
:
SELECT cu1.conversation_id
FROM conversation_user cu1
JOIN conversation_user cu2 USING (conversation_id)
LEFT JOIN conversation_user cu3 ON cu3.conversation_id = cu1.conversation_id
AND cu3.user_id NOT IN (3,32)
WHERE cu1.user_id = 32
AND cu2.user_id = 3
AND cu3.conversation_id IS NULL;
Eller NOT EXISTS
:
SELECT cu1.conversation_id
FROM conversation_user cu1
JOIN conversation_user cu2 USING (conversation_id)
WHERE cu1.user_id = 32
AND cu2.user_id = 3
AND NOT EXISTS (
SELECT 1
FROM conversation_user cu3
WHERE cu3.conversation_id = cu1.conversation_id
AND cu3.user_id NOT IN (3,32)
);
Begge forespørgsler ikke afhænge af en UNIQUE
begrænsning for (conversation_id, user_id)
, som måske er på plads eller ikke. Det betyder, at forespørgslen endda fungerer, hvis user_id
32 (eller 3) er opført mere end én gang for den samme samtale. Du ville få duplikerede rækker i resultatet, men skal anvende DISTINCT
eller GROUP BY
.
Den eneste betingelse er den, du formulerede:
Revideret forespørgsel
forespørgslen, du linkede til i kommentaren ville ikke virke. Du glemte at udelukke andre deltagere. Bør være noget i stil med:
SELECT * -- or whatever you want to return
FROM conversation_user cu1
WHERE cu1.user_id = 32
AND EXISTS (
SELECT 1
FROM conversation_user cu2
WHERE cu2.conversation_id = cu1.conversation_id
AND cu2.user_id = 3
)
AND NOT EXISTS (
SELECT 1
FROM conversation_user cu3
WHERE cu3.conversation_id = cu1.conversation_id
AND cu3.user_id NOT IN (3,32)
);
Hvilket ligner de to andre forespørgsler, bortset fra at det ikke returnerer flere rækker, hvis user_id = 3
er forbundet flere gange.