通过Rails sql查询查找属于两个不同用户的记录的方法有很多种
我在字符之间设置了一个消息传递系统,如下所示。每个角色都有通过::chats的多个对话,每个对话都有多个:消息,其中一些消息属于一个参与者,其余消息属于另一个参与者 character.rb通过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
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>)
第一种可能更快、更便携