Sql 选择相邻表中有多个其他行的行

Sql 选择相邻表中有多个其他行的行,sql,postgresql,Sql,Postgresql,我有一张名为“对话”的表格。除此之外,我还有一个名为“对话参与者”的表 当用户创建对话时,他们会选择要与哪些其他用户进行对话。在创建一个新的对话之前,我确实想检查一下,它是否已经存在于这一批参与者中——如果是的话,我只想重用现有的对话 所以我的问题是。如何在conversation中找到与conversation\u参与者有确切关系的行 我的桌子看起来像这样(简化) 现在的问题是。如何在conversation中找到包含conversation\u参与者的确切用户集的行?它必须是精确的集合,而不

我有一张名为“对话”的表格。除此之外,我还有一个名为“对话参与者”的表

当用户创建对话时,他们会选择要与哪些其他用户进行对话。在创建一个新的对话之前,我确实想检查一下,它是否已经存在于这一批参与者中——如果是的话,我只想重用现有的对话

所以我的问题是。如何在
conversation
中找到与
conversation\u参与者
有确切关系的行

我的桌子看起来像这样(简化)


现在的问题是。如何在
conversation
中找到包含
conversation\u参与者的确切用户集的行?它必须是精确的集合,而不仅仅是一个子集。

在列表中查找所有
对话的
参与者

SELECT c.id
FROM conversations AS c
WHERE NOT EXISTS (SELECT 1 FROM conversation_participants AS cp
                  WHERE cp.conversation = c.id
                    AND cp."user" NOT IN (/* list of users */));

您可以使用聚合。如果按字符串或数组的顺序构造参与者列表,则可以使用:

select cp.conversation
from conversation_participants cp
group by cp.conversation
having string_agg(user order by user, ',') = '1,2,3,4';
也可以在不使用字符串或数组的情况下执行此操作:

select cp.conversation
from conversation_participants cp
where user in (1, 2, 3, 4)
group by cp.conversation
having count(*) = 4;  -- all four users
如果将值作为数组传入:

select cp.conversation
from conversation_participants cp
where user i= any :ar
group by cp.conversation
having count(*) = cardinality(:ar)  -- all four users

以表格形式提供一些示例数据和预期输出您需要从
对话参与者
对话
的外键,否则您无法将参与者与对话关联。@LaurenzAlbe哦,是的。我有。我只是忘了把它放进去。我再加上,太好了!就是这样。我假设我只需要删除
而不是
,如果我想要一个对话,他们在列表中的位置?不。你想要一个所有参与者都在列表中的对话。这相当于找到一个列表中没有任何参与者的对话。确定所有对象是否都具有特定属性的方法是确保没有对象不具有该属性。前者不能很容易地用SQL写。这个答案有很多!这正是我需要的!
select cp.conversation
from conversation_participants cp
where user in (1, 2, 3, 4)
group by cp.conversation
having count(*) = 4;  -- all four users
select cp.conversation
from conversation_participants cp
where user i= any :ar
group by cp.conversation
having count(*) = cardinality(:ar)  -- all four users