根据多对多关系检索现有记录

Retrieving existing record based on its many-to-many relationship

我有一个基于以下架构构建的简单线程即时消息系统:

一个线程可以包含两个或多个用户,用户可以属于多个线程。当用户尝试创建新线程时,我需要检查用户(由 ID 指定)和 return 现有线程之间是否已存在现有线程。如果我指定的用户是该线程中的 只有 用户,我应该只 return 现有线程。

通常,我会使用这样的查询:

select distinct t.* from threads t
inner join thread_users tu on tu.thread_id = t.id
where tu.user_id in (1, 2);

但是,此查询将 return 个线程,其中两个用户(ID 12)不是 only 个用户那个线程。我真正需要的是 only in (1, 2) 子句之类的东西。

如何实现与 where only in 子句相同的效果?

编辑:从我发布后出现在边栏中的相关问题中得出这个:

select t.* from threads t
inner join thread_users tu on tu.thread_id = t.id
where tu.user_id in (1, 2)
having count(distinct tu.user_id) = 2;

似乎 有效,但我可能遗漏了一个我没有在数据库数据中考虑的边缘情况?

这是集合中集合子查询的示例:您要在线程中查找用户集合。我喜欢使用 group byhaving 来解决这些问题,因为这是一种非常灵活的方法。我认为以下内容可以满足您的需求:

select t.*
from threads t join
     thread_users tu
     on t.id = tu.thread_id
group by t.id
having sum(tu.user_id = 1) > 0 and
       sum(tu.user_id = 2) > 0 and
       sum(tu.user_id not in (1, 2)) = 0;

此查询将为您提供既有用户 1 也有 2 并且只有这些用户的线程想法:

SELECT t.id
FROM threads t join
     thread_users tu
     on t.id = tu.thread_id
GROUP by t.id
HAVING COUNT(distinct user_id) = 2
    AND SUM (CASE WHEN user_id NOT IN (1, 2) THEN 1 ELSE 0 END) = 0