MySQL分组查询获取每组最新记录问题求助
获取每个分组的最新记录的SQL实现方法
直接用GROUP BY product_number并不可靠——数据库会返回每组中任意一条非聚合列的记录(不同数据库行为有差异,比如MySQL关闭ONLY_FULL_GROUP_BY时会随机取值),你看到的“最早记录”只是巧合,不是预期结果。
下面提供几种靠谱的实现方式,不一定非要用表连接,按需选择:
方法1:窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等)
用ROW_NUMBER()窗口函数给每组记录按时间倒序编号,取编号为1的就是最新记录:
SELECT product_number, id, timestamp FROM ( SELECT product_number, id, timestamp, ROW_NUMBER() OVER (PARTITION BY product_number ORDER BY timestamp DESC) AS rn FROM your_table WHERE product_number IN (123, 456) ) t WHERE rn = 1;
如果同一product_number存在多条时间相同的最新记录,ROW_NUMBER()会随机保留一条;要是想保留所有时间相同的最新记录,可以换成RANK()。
方法2:子查询+表连接(兼容所有数据库)
先找出每个分组的最新时间,再关联原表拿到对应记录:
SELECT t.product_number, t.id, t.timestamp FROM your_table t JOIN ( SELECT product_number, MAX(timestamp) AS max_ts FROM your_table WHERE product_number IN (123, 456) GROUP BY product_number ) m ON t.product_number = m.product_number AND t.timestamp = m.max_ts;
注意:如果同一分组有多个记录的timestamp等于最大值,这条语句会返回所有符合条件的记录。
方法3:LIMIT+UNION ALL(适合分组数量少的场景)
逐个分组取最新记录,再用UNION ALL拼接结果:
(SELECT product_number, id, timestamp FROM your_table WHERE product_number = 123 ORDER BY timestamp DESC LIMIT 1) UNION ALL (SELECT product_number, id, timestamp FROM your_table WHERE product_number = 456 ORDER BY timestamp DESC LIMIT 1);
这种写法简单直观,但分组多的时候效率不如前两种。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

