MySQL如何实现先按created_at降序排序后按pid分组?
MySQL实现按pid分组并获取每组最新数据的方案
在MySQL中不能直接先排序再分组,因为SQL的执行顺序是先执行GROUP BY分组,再执行ORDER BY排序,分组操作会打乱之前的排序结果,直接写排序后分组的语句无法得到预期的每组最新数据。针对多表连接后的数据集,以下是两种可行的实现方案:
方案一:使用窗口函数(MySQL 8.0+ 推荐)
利用ROW_NUMBER()窗口函数,先对每个pid分组内的行按created_at降序编号,再筛选出编号为1的行(即每组最新数据)。
SELECT pid, created_at, xxx, yyy FROM ( SELECT a.pid, a.created_at, b.xxx, -- 替换为你的多表连接字段 c.yyy, -- 替换为你的多表连接字段 -- 按pid分组,组内按created_at降序编号 ROW_NUMBER() OVER (PARTITION BY a.pid ORDER BY a.created_at DESC) AS row_num FROM table_a a JOIN table_b b ON a.id = b.a_id -- 替换为你的多表连接条件 JOIN table_c c ON a.id = c.a_id -- 替换为你的多表连接条件 ) AS ranked_data WHERE row_num = 1;
如果存在同一pid下多条记录created_at相同的情况,可在ORDER BY后追加唯一字段(如id)保证结果唯一:
ROW_NUMBER() OVER (PARTITION BY a.pid ORDER BY a.created_at DESC, a.id DESC) AS row_num
方案二:关联子查询(兼容MySQL 5.x版本)
先通过子查询找出每个pid对应的最新created_at,再将子查询结果与原多表连接结果关联,匹配出对应的数据。
SELECT a.pid, a.created_at, b.xxx, c.yyy FROM table_a a JOIN table_b b ON a.id = b.a_id JOIN table_c c ON a.id = c.a_id -- 关联子查询得到每个pid的最新创建时间 JOIN ( SELECT pid, MAX(created_at) AS latest_created FROM table_a GROUP BY pid ) AS latest ON a.pid = latest.pid AND a.created_at = latest.latest_created;
注意:如果同一pid下有多个记录的created_at等于最大值,该方案会返回所有符合条件的记录。若需唯一结果,可在子查询中同时获取最大id(假设id自增),再添加a.id = latest.latest_id的关联条件。
内容的提问来源于stack exchange,提问作者prakashchhetri
相关产品推荐
相关产品推荐

