1

I am using the following query to get the latest 2 messages of the same conversation:

SELECT *
FROM messages
WHERE conversation_id
IN ( 122806, 122807 )
GROUP BY conversation_id
ORDER BY sent_on DESC
LIMIT 2

enter image description here

Which return message7 and message3 as result. What I need is to get latest 2 messages grouped by conversation_id, therefore the result should be:

message3
message1
message4
message5
Moussawi7
  • 12,359
  • 5
  • 37
  • 50

3 Answers3

1

The canonical way to do this is with a counter in the where clause:

select m.*
from message m
where 2 >= (select count(*)
            from message m2
            where m2.conversation_id = m.conversation_id and
                  m2.sent_on >= m.sent_on
           );

An index on message(conversation_id, sent_on) would definitely help this query. This also assumes that sent_on is unique. Otherwise, you can just use id.

A more efficient method is to use variables:

select m.*
from (select m.*,
             @rn := if(@conversation_id = conversation_id, @rn + 1, 1) as rn,
             @conversation_id := conversation_id
      from message m cross join
           (select @conversation_id := '', @rn := 0) const
      order by conversation_id, sent_on desc
     ) m
where rn <= 2;
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
1

One way to go about this using GROUP_CONCAT() and the SUBSTRING_INDEX() but it will show you the messages seperated by seperator you specified in the query with conversation id not as individual row foreach message,you can use ORDER BY clause in group_concat function also i have ORDER BY sent_on DESC so the messages will be grouped and ordered by sent_on

SELECT conversation_id,
SUBSTRING_INDEX(
GROUP_CONCAT(message ORDER BY sent_on DESC SEPARATOR '||'),
'||',2) two_messages
FROM messages
/*
optional where filter i have provided example for all conversations
 WHERE conversation_id 
IN ( 122806, 122807 ) */
GROUP BY conversation_id
ORDER BY sent_on DESC

Also note there is a default 1024 character limit set on GROUP_CONCAT() but you can also increase it by following the GROUP_CONCAT() manual

M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118
  • 1
    Thanks, It worked fine, but as you mentioned it show the message seperated by seperator, so you think that there are no way to achieve it by row?! – Moussawi7 Mar 28 '14 at 11:35
  • I guess there should be a way to go about getting the messages in each row but i can't have a solution for this :) – M Khalid Junaid Mar 28 '14 at 11:37
0

Try GROUP BY with ORDER BY something like this:

SELECT GROUP_CONCAT(messages)
FROM(
    SELECT *
    FROM messages
    ORDER BY sent_on DESC
    )temp
GROUP BY conversation_id
LIMIT 2;
avisheks
  • 1,178
  • 10
  • 27