3

我正在制作一个消息系统,就像在 facebook 上一样。当用户从他们的个人资料而不是从消息中向某人发送新消息时,我想检查数据库是否他们已经一起进行了对话。

我的表看起来像:

messages =>
  m_id (message id)
  t_id (thread id)
  author_id
  text

thread_recipients =>
  t_id (thread id)
  user_id (id of the user belonging to the thread/conversation)
  is_read

所以基本上我有一个属于对话的每个用户的行,每条消息都有一个属于它的线程。

因此,假设我的 user_id 为 14,而我正在写信的用户为 16。然后我需要找出这些行是否存在:

t_id    user_id    is_read
 x         16         1
 x         14         1

线程 ID 必须匹配,并且该线程中不应有任何其他用户。

这可以在一个查询中完成吗?

4

3 回答 3

3

您可以将线程接收者与自身进行一元连接,然后使用 where。

SELECT tr1.*,
       tr2.*
FROM thread_recipients tr1,
     thread_recpipients tr2
WHERE tr1.t_id = tr2.t_id
  AND tr1.user_id = WRITER_ID
  AND tr2.user_id = RECIPIENT_ID;

如果你想计数只需更换

tr1.*,tr2.*

count(*)

如果你想删除其他用户的线程,你可以尝试 Bohemian 的解决方案(我没有测试过,但怀疑是最有效的)或者这个:

SELECT tr1.*,
       tr2.*
FROM thread_recipients tr1,
     thread_recpipients tr2
WHERE tr1.t_id = tr2.t_id
  AND tr1.user_id = WRITER_ID
  AND tr2.user_id = RECIPIENT_ID AND
  NOT EXISTS(select t_id from thread_recipients where user_id not in (WRITER_ID, RECIPIENT_ID) limit 1);
于 2013-05-19T10:19:04.640 回答
1

将表连接到自身三次:

select tr1.t_id 
from thread_recepients tr1  
join thread_recepients tr2 on tr2.t_id = tr1.t_id 
    and tr2.user_id = 16
left join thread_recepients tr3 on on tr3.t_id = tr1.t_id
    and tr3.user_id not in (14, 16)
where tr1.user_id = 14
and tr3.user_id is null

根据is null您的要求,测试断言没有其他用户参与(没有其他行加入)对话:

不能是属于该线程的任何其他用户

因为我们希望找不到其他用户的连接行。


推荐指标:

create index thread_recepients_t_id on thread_recepients (t_id);
create index thread_recepients_user_id on thread_recepients (user_id);
于 2013-05-19T10:45:20.807 回答
1

这是可以获取行数的查询。所以你可以检查它是否是2。

select 
    count(*) 
from 
    thread_recepients tr1  
inner join 
     thread_recepients tr2 
on 
     tr1.t_id = tr2.t_id 
where 
     (tr1.user_id = 'someuderid' or tr2.user_id = 'theotherguy') 
于 2013-05-19T10:22:35.883 回答