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

Luc*_*oli 9 mysql sql

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

例如:表:消息

id  |  topic_id
------------
 1  |  1
 2  |  1
 3  |  1
 4  |  1
 5  |  2
 6  |  2
 7  |  2
 8  |  3
 9  |  3
10  |  3
Run Code Online (Sandbox Code Playgroud)

我想获取这些行:

 3 1
 4 1
 6 2
 7 2
 9 3
10 3
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

谢谢

小智 5

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
Run Code Online (Sandbox Code Playgroud)


Unr*_*son 2

你可以

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
Run Code Online (Sandbox Code Playgroud)

编辑:似乎 mysql 不允许(但是!在未来的版本中可能)在子查询中使用 LIMIT 这是一个通用的解决方案(没有捷径假设,除了 msg.id 对于每个 topic_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
Run Code Online (Sandbox Code Playgroud)

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