Dit is een geval van relationele verdeeldheid . We hebben een arsenaal aan technieken verzameld onder deze gerelateerde vraag:
De speciale moeilijkheid is om extra gebruikers uit te sluiten. Er zijn in principe 4 technieken.
Ik stel voor 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;
Of 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)
);
Beide zoekopdrachten doen niet afhankelijk van een UNIQUE
beperking voor (conversation_id, user_id)
, die al dan niet aanwezig zijn. Dit betekent dat de zoekopdracht zelfs werkt als user_id
32 (of 3) wordt meer dan eens vermeld voor hetzelfde gesprek. Je zou krijg echter dubbele rijen in het resultaat en moet DISTINCT
. toepassen of GROUP BY
.
De enige voorwaarde is degene die je hebt geformuleerd:
Gecontroleerde zoekopdracht
De query die je in de reactie hebt gelinkt zou niet werken. U bent vergeten andere deelnemers uit te sluiten. Zou zoiets moeten zijn als:
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)
);
Dit is vergelijkbaar met de andere twee zoekopdrachten, behalve dat er niet meerdere rijen worden geretourneerd als user_id = 3
is meerdere keren gekoppeld.