如何在含重复key的表中获取每个distinct key对应的最新记录?
获取每个唯一Key对应的最新记录解决方案
我来帮你搞定这个问题!从包含重复id的表中捞取每个唯一id对应的最新记录,这是SQL里超常见的需求,给你几个实用的解法:
首先先明确你的示例表和期望结果:
示例表数据
id | user | timestamp -----|----------|------------------------- aaa | user_5 | 2015-01-28 22:28:55.111 aaa | user_6 | 2015-01-29 22:28:55.111 aaa | user_1 | 2015-01-24 22:28:55.111 aaa | user_4 | 2015-01-27 22:28:55.111 aaa | user_8 | 2015-01-31 22:28:55.111 aaa | user_2 | 2015-01-25 22:28:55.111 aaa | user_0 | 2015-01-23 22:28:55.111 aaa | user_9 | 2015-01-22 22:28:55.111 zzz | user_new | 2015-01-22 22:28:55.111 aaa | user_3 | 2015-01-26 22:28:55.111 aaa | user_7 | 2015-01-30 22:28:55.111
期望结果
id | user | timestamp -----|----------|------------------------- aaa | user_8 | 2015-01-31 22:28:55.111 zzz | user_new | 2015-01-22 22:28:55.111
解法1:窗口函数(推荐,兼容性强)
这是处理这类分组取最新记录最直观的方式,用ROW_NUMBER()窗口函数给每个id分组内的记录按时间戳排序,然后取序号为1的那条:
SELECT id, user, timestamp FROM ( SELECT id, user, timestamp, -- 按id分组,组内按时间戳倒序排,分配序号 ROW_NUMBER() OVER (PARTITION BY id ORDER BY timestamp DESC) AS rn FROM your_table_name -- 替换成你的实际表名 ) t WHERE rn = 1;
原理说明:
PARTITION BY id:把相同id的记录归为一组ORDER BY timestamp DESC:每个分组内,从最新的时间戳开始排序ROW_NUMBER()给每个分组的记录分配递增序号,最新的记录序号是1,最后筛选rn=1就得到每个id的最新记录
解法2:关联子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.7及以前版本),可以先用子查询获取每个id的最大时间戳,再关联原表拿到对应的完整记录:
SELECT t1.id, t1.user, t1.timestamp FROM your_table_name t1 INNER JOIN ( -- 先分组获取每个id的最新时间戳 SELECT id, MAX(timestamp) AS max_ts FROM your_table_name GROUP BY id ) t2 ON t1.id = t2.id AND t1.timestamp = t2.max_ts;
注意:如果同一个id有多个记录的时间戳完全相同且都是最新的,这个方法会返回所有这些记录;如果只需要一条,可以根据实际情况调整(比如加LIMIT 1或者结合其他字段排序)。
解法3:DISTINCT ON(仅适用于PostgreSQL)
如果你用的是PostgreSQL,可以用DISTINCT ON语法简化操作:
SELECT DISTINCT ON (id) id, user, timestamp FROM your_table_name ORDER BY id, timestamp DESC;
原理说明:DISTINCT ON (id)会保留每个id对应的第一条记录,我们通过ORDER BY id, timestamp DESC让每个id的最新记录排在第一位,这样就能直接得到目标结果。
内容的提问来源于stack exchange,提问作者Liquidpie
相关产品推荐
相关产品推荐

