MySQL:如何使用GROUP BY子句获取分组后的最后出现记录
获取每组最后出现记录的几种方法
当然可以实现,但单纯靠GROUP BY brand直接拉所有字段是不行的——毕竟标准SQL里GROUP BY是用来做聚合计算的,不是直接筛选每组里的特定行。不同数据库里直接这么写甚至可能不合法(比如MySQL开启ONLY_FULL_GROUP_BY时),或者返回随机/第一条记录,这显然不是你要的结果。
下面给你几种靠谱的实现方式,适配不同的数据库场景:
1. 子查询关联法(通用所有数据库)
先通过GROUP BY找出每个brand对应的最大id(或最新日期),再关联原表拿到完整的记录:
SELECT t.* FROM your_table t INNER JOIN ( -- 先获取每个brand的最大id SELECT brand, MAX(id) AS max_id FROM your_table GROUP BY brand ) t_max ON t.brand = t_max.brand AND t.id = t_max.max_id;
如果你的“最后出现”是基于日期而非id,只需要把MAX(id)换成MAX(your_date_column),关联条件也改成日期匹配即可。
2. 窗口函数法(推荐,支持SQL标准的数据库)
如果你的数据库支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server、Oracle等),用ROW_NUMBER()是最简洁直观的方式:
SELECT * FROM ( SELECT *, -- 按brand分组,每组内按id降序排序,给行编号 ROW_NUMBER() OVER (PARTITION BY brand ORDER BY id DESC) AS rn FROM your_table ) t -- 取每组的第一行(也就是id最大的那条) WHERE rn = 1;
要是同一brand下有多个记录的id相同(或日期相同),你想保留所有这些“并列最后”的记录,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK()。
3. MySQL老版本专属写法(5.x及以下)
如果还在使用MySQL 5.x这类不支持窗口函数的版本,可以用关联子查询的方式:
SELECT * FROM your_table t WHERE id = ( SELECT MAX(id) FROM your_table WHERE brand = t.brand );
这种写法逻辑简单,但数据量较大时,要确保brand和id字段有索引,避免性能问题。
关键提醒
别试图用GROUP BY brand直接SELECT *来实现——这种写法在很多数据库里是不符合SQL标准的,结果也不可控。一定要通过聚合+关联,或者窗口函数的方式来精准筛选每组的目标记录。
内容的提问来源于stack exchange,提问作者Gai Kuroda
相关产品推荐
相关产品推荐

