【问题标题】:How to find parent row based on unique child rows?如何根据唯一的子行查找父行?
【发布时间】:2017-03-21 12:41:11
【问题描述】:

我的架构(MySQL、InnoDb):

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

User
----
id (int)

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

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

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

所以我要选择:

  • 与 User1、User2 的对话

但不是:

  • 与 User1、User2、User3 的对话
  • 与 User1 的对话
  • 与 User1、User3 的对话
  • 等

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

【问题讨论】:

    标签: mysql yii2


    【解决方案1】:

    您可以在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 版本慢。您需要测试这两种解决方案,看看哪个更适合您。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-05
      • 2014-11-09
      相关资源
      最近更新 更多