これは関係分割の場合です 。私たちはこの関連する質問の下で技術の武器を集めました:
特別な難しさは、追加のユーザーを除外することです。基本的に4つのテクニックがあります。
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;
または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)
);
どちらのクエリもしません UNIQUE
に依存します (conversation_id, user_id)
の制約 、配置されている場合とされていない場合があります。つまり、user_id
の場合でも、クエリは機能します 32(または3)は、同じ会話に対して複数回リストされています。あなたは ただし、結果に重複する行が含まれるため、DISTINCT
を適用する必要があります またはGROUP BY
。
唯一の条件はあなたが作成したものです:
監査済みクエリ
コメントでリンクした
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)
);
これは他の2つのクエリと似ていますが、user_id = 3
の場合に複数の行を返さない点が異なります。 複数回リンクされています。