如何为MySQL中的每个topic_id选择最后两条记录

时间:2010-04-07 23:01:59

标签: sql mysql

我必须为每个主题选择最后两条记录。

例如: table:msg

id  |  topic_id
------------
 1  |  1
 2  |  1
 3  |  1
 4  |  1
 5  |  2
 6  |  2
 7  |  2
 8  |  3
 9  |  3
10  |  3

我想获取这些行:

 3 1
 4 1
 6 2
 7 2
 9 3
10 3

我该怎么做?

感谢

4 个答案:

答案 0 :(得分:4)

SELECT max(id), max(topic_id) FROM msg
GROUP BY topic_id

UNION

SELECT max(id), max(topic_id) FROM msg
WHERE id not in (
    SELECT max(id) as id FROM msg
    GROUP BY topic_id)
GROUP BY topic_id

答案 1 :(得分:3)

SQL不支持LIM后跟IN子句的工作很简单。只需在IN子句中构建另一个子查询。例如。

SELECT a.id, a.topic_id
FROM MSG a
WHERE a.id IN (
    SELECT t.id
    FROM (Select * from MSG t
    WHERE a.topic_id = t.topic_id
    ORDER BY t.id DESC
    LIMIT 2)alias)
ORDER BY a.topic_id, a.id

让我知道这对你有用。

答案 2 :(得分:1)

你可以

SELECT a.id, a.topic_id
FROM MSG a
WHERE a.id IN (
    SELECT t.id
    FROM MSG t
    WHERE a.topic_id = t.topic_id
    ORDER BY t.id DESC
    LIMIT 2 )
ORDER BY a.topic_id, a.id

编辑: 因为看起来mysql不允许(在未来的版本中可能)在子查询中使用LIMIT这里是一个通用的解决方案(没有捷径假设,除了每个topic_id的msg.id是唯一的):

SELECT a.id, a.topic_id
FROM MSG a
WHERE a.id IN (
    SELECT MAX(t.id)
    FROM MSG t
    WHERE a.topic_id = t.topic_id
              ) OR
      a.id IN (
    SELECT MAX(t.id)
    FROM MSG t
    WHERE a.topic_id = t.topic_id AND 
    t.id NOT IN (
        SELECT MAX(t2.id)
        FROM MSG t2
        WHERE t.topic_id = t2.topic_id
                )
              )       
ORDER BY a.topic_id, a.id

当然这不太好,但你有。如果假设topic_id中的id是升序而没有漏洞,则可以进一步改进查询。

答案 3 :(得分:0)

我想知道更好的答案,但以下查询将有效。

SELECT * FROM msg where id in (SELECT m.id FROM msg m group by topic_id ) 
          or id in (SELECT m1.id FROM msg m1 where id not in (SELECT m2.id FROM msg m2  roup by topic_id )
group by topic_id) order by id