我有一个会话表和一个用户对话表。
CONVERSATION
Id, Subject, Type
USERCONVERSATION
Id, UserId, ConversationId
我需要根据UserIds列表进行SQL查询。所以,如果我对同一个ConversationId有三个UserId,我需要执行一个查询,如果我提供相同的三个userIds,它将返回ConversationId,它们完全匹配。
答案 0 :(得分:4)
假设同一用户不能两次进入UserConversation:
SELECT ConversationID
FROM UserConversation
GROUP BY ConversationID
HAVING
Count(UserID) = 3 -- this isn't necessary but might improve performance
AND Sum(CASE WHEN UserID IN (1, 2, 3) THEN 1 ELSE 0 END) = 3
这也有效:
SELECT ConversationID
FROM
UserConversation UC
LEFT JOIN (
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
) U (UserID) ON UC.UserID = U.UserID
GROUP BY ConversationID
HAVING
Count(U.UserID) = 3
AND Count(UC.UserID) = 3
如果您发现其中任何一个查询的效果都很差,那么两步法可能有所帮助:首先查找包含至少所需各方的所有会话,然后从该集合中排除那些包含任何其他人。索引当然会产生很大的不同。
从UserConversation中删除ID列将通过每页获取更多行来提高性能,从而每次读取更多数据(大约多50%!)。如果您的Id列不仅是PK而且还是聚集索引,那么立即将聚集索引更改为ConversationId, UserId
(反之亦然,具体取决于最常见的用法)!
如果您在发表评论时需要性能方面的帮助,我会尽力帮助您。
P.S。这是另一个疯狂的想法,但它可能表现不佳(虽然有时会让你感到惊讶):
SELECT
Coalesce(C.ConversationID, UC.ConversationID) ConversationID
-- Or could be Min(C.ConversationID)
FROM
Conversation C
CROSS JOIN (
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
) U (UserID)
FULL JOIN UserConversation UC
ON C.ConversationID = UC.ConversationID
AND U.UserID = UC.UserID
GROUP BY Coalesce(C.ConversationID, UC.ConversationID)
HAVING Count(*) = Count(U.UserID)
答案 1 :(得分:0)
我的解决方案错了,不幸的是...... 我强烈建议使用Erik's solutions ...
之一此致