2017-04-11 26 views
2

我有消息表格式如下:從信息表中查詢對話

+------------------------------------------------------------------+ 
| id|sender_id| recipient_id | message_text |created_at   | 
+------------------------------------------------------------------+ 
| 1 | 2  | 10   | "test1"  |"2017-04-10 09:05:45" | 
| 2 | 10  | 2   | "test2"  |"2017-04-10 09:05:47" | 
| 3 | 2  | 4   | "test3"  |"2017-04-10 09:05:49" | 
| 4 | 10  | 4   | "test4"  |"2017-04-10 09:05:51" | 
| 5 | 4  | 2   | "test5"  |"2017-04-10 09:05:53" | 
| 6 | 2  | 10   | "test6"  |"2017-04-10 09:05:58" | 
+------------------------------------------------------------------+ 

我想要做的就是讓所有的「對話」一登錄的用戶(比如ID爲2的用戶) ,以及該對話的最後消息。 我設法拔出用戶用戶2的ID的擁有與使用此查詢消息:

select distinct users.id 
from messages, users where 
(recipient_id = 2 and users.id = sender_id) 
or 
(sender_id = 2 and users.id = recipient_id); 

這是什麼產生是

4 
10 

爲用戶2已經無論是從這兩個人發送和/或接收的消息(test1, test2, test6對於10test3, test5對於4)。

我不能做的就是修改這個查詢,從而也產生了由產生的ID發送或接收的最後一條消息 - 例如

4 | test5 
10 | test6 

回答

3

如果我正確理解您的要求,您希望獲取涉及某個用戶的每個對話的最新消息日期。在這種情況下,我們可以聚合某個給定用戶的會話並保留最近的消息日期。

SELECT m1.* 
FROM messages m1 
INNER JOIN 
(
    SELECT LEAST(sender_id, recipient_id) AS first, 
      GREATEST(sender_id, recipient_id) AS second, 
      MAX(created_at) AS recent_date 
    FROM messages 
    WHERE sender_id = 2 OR recipient_id = 2 
    GROUP BY LEAST(sender_id, recipient_id), 
      GREATEST(sender_id, recipient_id) 
) m2 
    ON LEAST(m1.sender_id, m1.recipient_id) = m2.first AND 
     GREATEST(m1.sender_id, m1.recipient_id) = m2.second AND 
     m1.created_at = m2.recent_date 

輸出:

enter image description here

說明:

在此查詢的挑戰是要找到一種方法,兩個用戶之間共同羣組對話。我使用了LEAST/GREATEST技巧,這是我們可以將2 -> 44 -> 2對話視爲邏輯上相同的一種方式。然後,使用GROUP BY,我們可以確定該對通話用戶的最近對話日期。因此,在我上面的答案中的子查詢發現,對於每一對用戶,不考慮任何順序,以及它最近的對話日期。然後,我們將此結果返回到messages表中,以引入實際的最新消息文本。

演示在這裏:

Rextester

+0

這確實給了我幾乎所需的結果,但我需要最近的消息而不是他們的日期。如果我只是添加消息文本進行選擇,那麼您使用日期所做的部分仍然正確,但我收到的消息與日期不匹配。我喜歡這個方法,你能不能解釋一下你是如何得到這個解決方案的? – hpdobrica

+0

修改後的查詢就像一個魅力!我真的很想聽聽你在那裏做了些什麼,我不想只是複製/粘貼它哈哈:) – hpdobrica

+0

@hpdobrica我給了你一個更深的解釋。 –

0

使用在查詢結束到order_by created_at desc聲明獲取最近的消息。

+1

這將不會得到預期的結果,因爲你的做法會離開我們只是一個記錄。 –

+0

'選擇不同users.id,從消息messages.message_text ,用戶 其中 (recipient_id = 2和users.id = SENDER_ID) 或 (SENDER_ID = 2和users.id = recipient_id)由messages.created_at降序順序;' 這給我所有的消息從/從用戶2從最新到最舊排序。另外當我添加message_text選擇,我不再只獲得2條記錄,但所有的消息,這也是問題的一部分。 – hpdobrica