如何根据唯一的子行查找父行?

时间:2017-03-21 12:41:12

标签: mysql yii2

我的架构(MySQL,InnoDb):

Conversation
------------
id (int)

User
----
id (int)

UserConversation
----------------
user_id (int, FK)
conversation_id (int, FK)

只需将用户映射到对话(多对多)。

现在,在我在user1和user2之间创建新的对话之前,我想检查这两个用户之间的对话是否已存在于DB中。

所以我想选择:

  • 与User1,User2的对话

但不是:

  • 与User1,User2,User3的对话
  • 与User1的对话
  • 与User1,User3的对话

换句话说:我的目标是防止在用户组之间创建重复的对话。如何实现这一点是Yii2 ActiveRecord还是纯SQL查询?

1 个答案:

答案 0 :(得分:2)

您可以在where子句中使用一系列存在/不存在的条件来确定conversation是否仅在特定用户之间。唯一的缺点是,对于每个用户,您需要添加新的exists条件:

select c.id
from conversation c
where exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id=1)
      and exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id=2)
      and not exists (select 1 from userconversations uc where uc.conversation_id=c.id and uc.user_id not in (1,2))

另一种方法是比较记录计数:

select conversation_id, count(if(user_id in (1,2),1,null)) as in_user, count(*) as all_user
from userconversations uc
group by conversation_id
having in_user=2 and all_user=2

如果列表中有超过2个用户,则此查询不需要where子句中的其他条件,但由于条件计数,可能比exists版本慢。您需要测试两种解决方案,看看哪种解决方案更适合您。