2012-11-03 230 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