首页 / MySQL / 正文

[MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?

11326 发布于: 2018-04-26 读完约需4分钟

问题描述

比如,在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

如果执行MySQL分组查询语句,如下:

select * from messages group by name

则会返回所有按name分组的第一条数据,如下:

1    A       A_data_1
4    B       B_data_1
6    C       C_data_1

那么,如何查询按name分组后返回每组最后一条数据的MySQL语句呢,返回的结果如下:

3    A       A_data_3
5    B       B_data_2
6    C       C_data_1

方案一

MySQL 8.0版本以前,可以使用如下的语句:

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;

MySQL 8.0版本中,MySQL新增了对窗口函数(Window Functions)的支持,我们可以使用窗口函数来简化SQL查询语句,并且不需要使用GROUP BY子句,如下:

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;

方案二

使用MySQLIN(...)子句,如下:

SELECT id, name, other_columns
FROM messages
WHERE id IN (
    SELECT MAX(id)
    FROM messages
    GROUP BY name
);

方案三

使用MySQLGROUP_CONCATSUBSTRING_INDEX来查询,如下:

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

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

上一篇: [MySQL]MySQL数据库中如何在SELECT查询中使用IF语句判断某个列的值?

下一篇: [LINQ]收集.NET/C#应用程序开发中一些好的/有用的关于LINQ的非微软官方的静态扩展方法

本文永久链接码友网 » [MySQL]MySQL数据库中如何查询分组后每组中的最后一条记录?

分享扩散:

发表评论

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