在分组前使用限制

时间:2014-03-28 11:08:08

标签: mysql sql

我使用以下查询来获取同一会话的最新2条消息:

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

enter image description here

结果返回message7message3。 我需要的是获取按conversation_id分组的最新2条消息,因此结果应为:

message3
message1
message4
message5

3 个答案:

答案 0 :(得分:1)

执行此操作的规范方法是使用where子句中的计数器:

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
           );

message(conversation_id, sent_on)上的索引肯定有助于此查询。这也假定sent_on是唯一的。否则,您只需使用id

更有效的方法是使用变量:

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;

答案 1 :(得分:1)

使用GROUP_CONCAT()SUBSTRING_INDEX()进行此操作的一种方法,但它会显示您在查询中指定的分隔符所分隔的消息,其中对话ID不是单独的行foreach消息,您可以使用group_concat函数中的ORDER BY子句也有ORDER BY sent_on DESC,因此消息将按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

另请注意,GROUP_CONCAT()上设置了默认的1024字符限制,但您也可以按照GROUP_CONCAT()手册

来增加它

答案 2 :(得分:0)

尝试使用ORDER BY的GROUP BY:

SELECT GROUP_CONCAT(messages)
FROM(
    SELECT *
    FROM messages
    ORDER BY sent_on DESC
    )temp
GROUP BY conversation_id
LIMIT 2;