首页 / MySQL / 正文

[MySQL]MySQL数据库如何按某列分组排序后查询每个分组的最后一条数据?

6536 发布于: 2018-01-16 读完约需7分钟

https://stackoverflow.com/questions/1313120/retrieving-the-last-record-in-each-group
[MySQL]MySQL数据库如何按某列分组排序后查询每个分组的最后一条数据?

比如当前有如下的消息表(messages)及示例数据:

Id   Name   Other_Columns
-------------------------
1    A       A_data_1
2    A       A_data_2
3    A       A_data_3
4    B       B_data_1
5    B       B_data_2
6    C       C_data_1

按照以下SQL语句查询:

select * from messages group by name

得到的查询结果为:

1    A       A_data_1
4    B       B_data_1
6    C       C_data_1

如何使用SQL语句查询每个分组的最后一条数据,如:

3    A       A_data_3
5    B       B_data_2
6    C       C_data_1

方案一

SELECT m1.*
FROM messages m1 LEFT JOIN messages m2
 ON (m1.name = m2.name AND m1.id < m2.id)
WHERE m2.id IS NULL;

如果中MySQL 8.0中,可以使用 WITH 的语法(WITH语法文档),具体实现SQL语句如下:

WITH ranked_messages AS (
  SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn
  FROM messages AS m
)
SELECT * FROM ranked_messages WHERE rn = 1;

方案二

使用子查询

select
    a.*
from
    messages a
    inner join 
        (select name, max(id) as maxid from messages group by name) as b on
        a.id = b.maxid

如果不是以 id 列排序的,则指定其他列即可,如:

select
    a.*
from
    messages a
    inner join 
        (select name, max(other_col) as other_col 
         from messages group by name) as b on
        a.name = b.name
        and a.other_col = b.other_col

方案三

SELECT
  Id, Name, OtherColumns
FROM messages
WHERE NOT EXISTS (
  SELECT * FROM messages as M2
  WHERE M2.Name = messages.Name
  AND M2.Id > messages.Id
)

方案四

SELECT jos_categories.title AS name,
       joined .catid,
       joined .title,
       joined .introtext
FROM   jos_categories
       INNER JOIN (SELECT *
                   FROM   (SELECT `title`,
                                  catid,
                                  `created`,
                                  introtext
                           FROM   `jos_content`
                           WHERE  `sectionid` = 6
                           ORDER  BY `id` DESC) AS yes
                   GROUP  BY `yes`.`catid` DESC
                   ORDER  BY `yes`.`created` DESC) AS joined
         ON( joined.catid = jos_categories.id )

方案五

SELECT 
  `Id`,
  `Name`,
  SUBSTRING_INDEX(
    GROUP_CONCAT(
      `Other_Columns` 
      ORDER BY `Id` DESC 
      SEPARATOR '||'
    ),
    '||',
    1
  ) Other_Columns 
FROM
  messages 
GROUP BY `Name`

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [MySQL]MySQL数据库中如何查询出所有包含指定的一个或者多个字段名(列名)的数据表集合?

下一篇: [MySQL]MySQL数据库中插入操作时先判断数据是否存在,不存在则插入数据,存在则更新数据

本文永久链接码友网 » [MySQL]MySQL数据库如何按某列分组排序后查询每个分组的最后一条数据?

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册