Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过Rails sql查询查找属于两个不同用户的记录的方法有很多种_Sql_Ruby On Rails_Activerecord - Fatal编程技术网

通过Rails sql查询查找属于两个不同用户的记录的方法有很多种

通过Rails sql查询查找属于两个不同用户的记录的方法有很多种,sql,ruby-on-rails,activerecord,Sql,Ruby On Rails,Activerecord,我在字符之间设置了一个消息传递系统,如下所示。每个角色都有通过::chats的多个对话,每个对话都有多个:消息,其中一些消息属于一个参与者,其余消息属于另一个参与者 character.rb has_many :chats, foreign_key: "character_id", dependent: :destroy has_many :conversations, through: :chats, source: :conversation has_m

我在字符之间设置了一个消息传递系统,如下所示。每个角色都有通过::chats的多个对话,每个对话都有多个:消息,其中一些消息属于一个参与者,其余消息属于另一个参与者

character.rb

has_many :chats,  foreign_key: "character_id",
                  dependent: :destroy
has_many :conversations, through: :chats, source: :conversation
has_many :messages
会话.rb

has_many :messages
聊天室

belongs_to :character
belongs_to :conversation
message.rb

belongs_to :character
belongs_to :conversation
因此,两个字符Alf character_id:1和Baz character_id:2之间的对话将涉及聊天表中具有相同对话_id 10的两行,例如:

Chats
character_id    conversation_id
1               10
2               10
可能存在另一个会话_id:23,其中Alf和Baz都涉及第三个用户Cal,字符_id:7:

Chats
character_id    conversation_id
1               23
2               23
7               23
重要的是,查询不选择此组对话

我的问题是,如何构造一个SQL查询来只查找Alf和Baz之间的对话

我被卡住了,因为有三个步骤,所以有三个SQL查询:首先必须找到属于Alf的所有对话,然后从这些对话中选择也属于Baz的对话,最后从这些对话中选择只属于Alf和Baz的对话。如何在一个数据库中“链接”三个sql查询

我的想法是这样的:

alf_id = @alf.id
baz_id = @baz.id
find_by_sql("  SELECT      *
               FROM        Chats
               RIGHT JOIN  Conversations
               ON          Chats.character_id = #{alf_id}
               SELECT      *
               FROM        Conversations
               INNER JOIN  Chats
               ON          Chats.conversation_id = Conversations.id
               AND         Chats.character_id = #{baz_id}
               WHERE       (conversation belongs to only 2 characters)
           ; ")
编辑 可能的解决方案? 有人能说这是否正确吗

sender_id    = @sender.id
recipient_id = @recipient.id
conversationID = find_by_sql("
      SELECT Conversations.id FROM
      (
            (
                  (
                        Conversations INNER JOIN ( Chats WHERE Chats.character_id=#{sender_id} )
                                      ON Chats.conversation_id=Conversations.id
                  )
                  INNER JOIN ( Chats WHERE Chats.character_id = #{recipient_id} )
                        ON Chats.conversation_id=Conversations.id
            )
            GROUP BY conversation_id
                  HAVING COUNT(Chats.conversation_id)=2
      )
; ")
大概是这样的:

select conversation_id
from conversations
group by conversation_id
having
        count(case when character_id = <ch1> then 1 end) = 1
    and count(case when character_id = <ch2> then 1 end) = 1
    and count(*) = 2
另一个选择是:

select conversation_id from conversations where character_id = <ch1>
intersect
select conversation_id from conversations where character_id = <ch2>
except
select conversation_id from conversations where character_id not in (<ch1>, <ch2>)
第一种可能更快、更便携