我正在建立一个消息系统,就像在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必须匹配,并且该线程中不应该有任何其他用户。
这可以在一个查询中完成吗?
答案 0 :(得分: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);
答案 1 :(得分: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')
答案 2 :(得分: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);