Đây là một trường hợp của phép chia quan hệ . Chúng tôi đã tập hợp một kho kỹ thuật theo câu hỏi liên quan này:
Khó khăn đặc biệt là loại trừ người dùng bổ sung. Về cơ bản có 4 kỹ thuật.
Tôi đề nghị 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;
Hoặc 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)
);
Cả hai truy vấn đều không không phụ thuộc vào một UNIQUE
ràng buộc cho (conversation_id, user_id)
, có thể có hoặc không. Có nghĩa là, truy vấn thậm chí hoạt động nếu user_id
32 (hoặc 3) được liệt kê nhiều hơn một lần cho cùng một cuộc trò chuyện. Bạn sẽ Tuy nhiên, nhận được các hàng trùng lặp trong kết quả và cần áp dụng DISTINCT
hoặc GROUP BY
.
Điều kiện duy nhất là điều kiện bạn đã xây dựng:
Truy vấn được kiểm tra
truy vấn bạn đã liên kết trong nhận xét sẽ không hoạt động. Bạn đã quên loại trừ những người tham gia khác. Phải là một cái gì đó như:
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)
);
Tương tự với hai truy vấn còn lại, ngoại trừ việc nó sẽ không trả về nhiều hàng nếu user_id = 3
được liên kết nhiều lần.