如何结合使用MySQL GROUP BY与ORDER BY获取每组最后一行
我明白你想要的是按post_type分组后,拿到每组里ID最大的那条记录——也就是每组的最后一条数据对吧?之前的两种写法都没达到预期,问题确实出在MySQL对GROUP BY和子查询排序的处理逻辑上,我来给你拆解下原因,再提供两种可行的方案:
为什么之前的写法失效?
- 第一种写法
SELECT ID, post_type FROM wp_posts GROUP BY post_type ORDER BY ID DESC;:这里的ORDER BY只是对分组后的结果做整体排序,但GROUP BY本身并不会保证选取每组里ID最大的记录——MySQL只会从每组中随机选取一条符合条件的记录(通常是物理存储中较早的那条),所以你拿到的不是每组的最后一行。 - 第二种子查询写法:虽然你先对
wp_posts按ID降序排序,但MySQL优化器在处理GROUP BY时,会忽略子查询里的ORDER BY(因为它认为分组不需要依赖排序后的顺序),最终还是随机选取了每组里的某条记录,不符合你的预期。
解决方案1:使用窗口函数(推荐,适配MySQL 8.0+/MariaDB 10.2+)
窗口函数ROW_NUMBER()可以精准给每组记录按ID降序编号,编号为1的就是每组ID最大的那条记录,SQL如下:
SELECT ID, post_type FROM ( SELECT ID, post_type, ROW_NUMBER() OVER (PARTITION BY post_type ORDER BY ID DESC) AS rn FROM wp_posts ) AS ranked_posts WHERE rn = 1;
逻辑说明:
PARTITION BY post_type:把数据按post_type分组ORDER BY ID DESC:让每组内的记录按ID从大到小排序ROW_NUMBER():给每组的记录编序号,最大ID的那条序号为1- 最后筛选
rn=1的记录,就是你要的每组最后一行
解决方案2:关联子查询(兼容旧版本MySQL)
如果你的MySQL版本较低,不支持窗口函数,可以用关联子查询先找出每组的最大ID,再关联原表获取对应记录:
SELECT p.ID, p.post_type FROM wp_posts p INNER JOIN ( SELECT post_type, MAX(ID) AS max_id FROM wp_posts GROUP BY post_type ) AS max_ids ON p.post_type = max_ids.post_type AND p.ID = max_ids.max_id;
逻辑说明:
- 子查询
max_ids按post_type分组,计算出每组的最大ID - 将原表与子查询关联,匹配每个
post_type对应的最大ID记录
以上两种方法都能得到你期望的结果:
Id | post_type 1900| attachment 1672| nav_menu_item 1668| page 1899| post
内容的提问来源于stack exchange,提问作者Chigozie Madubuko
相关产品推荐
相关产品推荐

