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.