2016-06-14 38 views
2

我有消息表(爲person_id,消息,conversation_id,created_at)一是爲了通過,然後由集團

我想每個談話。我曾嘗試與子查詢最新的消息,但它似乎忽略子查詢中的我的orderby:

SELECT sub.* FROM 
     (SELECT * FROM messages ORDER BY created_at DESC) AS sub 
GROUP BY sub.conversation_id 

在此SQLfiddle中試一試。

任何其他方式來獲得正確的結果?

http://sqlfiddle.com/#!9/12739/1

+1

對不起使用其中一個選擇組!這是一個錯誤:) –

+0

可能重複[mysql-order-by-before-group-by](http://stackoverflow.com/questions/14770671/mysql-order-by-before-group-by) – BJones

回答

2

如果你希望所有的每個對話樂特的消息,你可以通過

SELECT messages.* 
FROM messages 
WHERE (messages.created_at, messages.conversation_id) in 
    (SELECT max(created_at) , conversation_id 
    FROM messages messages 
    Group by conversation_id); 
+0

謝謝你! 這是最優化的方式嗎? –

+1

另一種方法是將同一個表上的內部聯接分組爲..可能asnwer中的查詢是最優化的..但結果可能取決於表的實際人口.. – scaisEdge

1

試試這個方法:

SELECT m1.* 
FROM messages AS m1 
JOIN (
    SELECT conversation_id, MAX(created_at) AS created_at 
    FROM messages 
    GROUP BY conversation_id 
) AS m2 ON m1.conversation_id = m2.conversation_id AND m1.created_at = m2.created_at 
1

上sqlfiddle無法對此進行測試,它不工作對我來說:

SELECT m1.* 
    FROM messages m1 
WHERE m1.created_at = 
     (SELECT max(created_at) 
     FROM messages m2 
     where m1.conversation_id=m2.conversation_id) 
1

您可以用相關子查詢做到這一點在選擇列表中,或者將from列表中的子查詢連接回主表。

相關子查詢:在

SELECT DISTINCT m1.conversation_id, (SELECT * FROM messages m2 WHERE m2.conversation_id=m1.conversation_id ORDER BY created_at DESC LIMIT 1) 
FROM messages m1 

子查詢from子句:

SELECT m1.* 
FROM messages as m1 
JOIN (
    SELECT conversation_id, max(created_at) AS max_created_at 
    FROM messages 
    GROUP BY conversation_id 
) m2 on m1.conversation_id = m2.conversation_id and m1.created_at = m2.max_created_at 

2方法之間的區別在於,相關子查詢總是會返回1個記錄每個對話id。如果2個記錄具有相同的created_at值,則每個對話可以返回多於1條記錄。如果有一個自動遞增的id字段唯一標識每條消息,那麼您可以使用此字段的最大值而不是創建的字段來解決此潛在問題。