2012-11-03 136 views
1

我编码用于用户通信的消息系统。在收件箱中,我不想向用户显示他/她收到的消息。我只想展示对话。因此,作为一个例子,如果一个用户发送或在收件箱中,然后接收一个以上的消息应该只有会话(其包括所述最新消息,书面或接收的)与用户,并且当用户点击该对话他/她可以看到所有以前的消息。消息:显示对话

表结构“消息”的(简化的)是如下:

message_id 
user_id_sender 
user_id_recipient 
message 

现在的问题是,该消息被保存在数据库中,其中每一行是一个消息,所以我必须组这些消息以某种方式。

我想出的select语句如下:

SELECT * FROM messages 
WHERE user_id_sender = 1 OR user_id_recipient = 1 
GROUP BY user_id_sender 

但现在我显然得到,因为一个已被写入用户“1”,表示已经收到一个两个消息..

是否有人有一个想法如何解决这个问题?

+0

因此,数据库中有两个条目用于发送每条消息? –

回答

2

我在一个月前解决了这个问题。我想你也有一个date字段。这个查询给你一个结构良好的结果,包含最后一条消息和最后一条消息的日期

$qry = 'SELECT 
CONCAT(GREATEST(user_id_sender,user_id_recipient)," ",LEAST(user_id_sender,user_id_recipient)) AS thread, 
MAX(CONCAT(date,"|",message)) as date_message, 
MAX(date) AS last_message, 
messages.* 
    FROM messages 
    WHERE user_id_sender= ? || user_id_recipient=? GROUP BY thread ORDER BY last_message DESC'; 

$rows = $db->fetchAll($qry, Array($current_user_id,$current_user_id)); 
+0

非常感谢你的回答。这工作得很好,但我得到了“[BLOB - 25 Bytes]”为date_message字段。我怎么能比从date_message字段中提取消息? – Freddy

+0

发生这种情况是因为不同类型的组连接将在二进制字段中转换。但是当你使用php得到结果并且你使'explode(“|”,$ row ['last_message'])' –

0

你得到只有一个消息,只要消息(message_id)是唯一的。当然,如果有更长时间的通信正在进行,您将收到多条消息。

N.B:你不需要group by在这里,因为这是只用于聚合列,例如:

SELECT user_id_sender, sum(*) FROM messages 
GROUP BY user_id_sender; 

你在哪里得到每个用户已发送的邮件的总和。

所以,如果你想看到通信的两个用户之间:

SELECT * FROM messages 
WHERE user_id_sender = 1 OR user_id_recipient = 1; 

您可以在此进一步限制,如果要存储时间戳以及,message_time例如或限制的消息数显示:

select * from ... limit 10; 
2

假设message_id是升序(即更高的ID是为以后的消息)。 @user_id是只为你正在寻找在收件箱中的user_id的占位符。我用安德烈的伎俩获得other_recipient_id简洁。

Select 
    mm.other_recipient_id, 
    m.* 
From (
    Select 
    user_id_sender + user_id_recipient - @user_id as other_recipient_id, 
    Max(message_id) as message_id 
    From 
    messages 
    Where 
    user_id_sender = @user_id Or 
    user_id_recipient = @user_id 
    Group By 
    user_id_sender + user_id_recipient - @user_id 
) mm 
    Inner Join 
    messages m 
    On 
    mm.message_id = m.message_id 

例拨弄http://sqlfiddle.com/#!2/05d191/3/0

0

假设我们想看到的与某些_ ID _用户交谈,这个查询可能是有用的:

SELECT (user_id_sender + user_id_recipient) - _ID_ AS correspondent, COUNT(*) AS total 
FROM messages 
WHERE user_id_sender = _ID_ OR user_id_recipient = _ID_ 
GROUP BY (user_id_sender + user_id_recipient) 

所得查询返回另一个的ID会话的用户(“通讯员”)和两个用户之间的消息数量(“总数”)。

Regards

+0

我喜欢你的方法来获取correspondent_id,我用我的答案取代了一个更麻烦的案例陈述。 – Laurence