如何按account_id分组返回最新记录并获取对应change_guid?
最佳解决方案推荐
方法一:用窗口函数ROW_NUMBER()(最通用高效)
这是最稳妥的方案,通过窗口函数按account_id分组,对InsertDateTime倒序排序,直接取每组第一条记录:
SELECT account_id, InsertDateTime, change_guid FROM ( SELECT account_id, InsertDateTime, change_guid, -- 按account_id分组,时间最新的排第1 ROW_NUMBER() OVER (PARTITION BY account_id ORDER BY InsertDateTime DESC) AS rn FROM change_records_archive WHERE change_type = 'Programme' ) t WHERE rn = 1;
如果遇到同一account_id下多条记录时间完全相同的情况,可按需调整:
- 换成
RANK():会返回所有时间最大的记录 - 换成
DENSE_RANK():和RANK()逻辑类似,但排名不会出现跳跃
方法二:修正CROSS APPLY写法
你之前用APPLY效果不对,大概率是写法有误,正确的写法应该是这样:
SELECT cr.account_id, latest.InsertDateTime, latest.change_guid FROM ( -- 先拿到所有唯一的account_id SELECT DISTINCT account_id FROM change_records_archive WHERE change_type = 'Programme' ) cr CROSS APPLY ( -- 为每个account_id匹配最新的那条记录 SELECT TOP 1 InsertDateTime, change_guid FROM change_records_archive WHERE account_id = cr.account_id AND change_type = 'Programme' ORDER BY InsertDateTime DESC ) latest;
这种写法适合SQL Server等支持APPLY语法的数据库,和窗口函数效果一致。
方法三:关联子查询匹配最大时间
先通过子查询拿到每个account_id的最新时间,再关联原表获取对应的change_guid:
SELECT cr.account_id, cr.InsertDateTime, cr.change_guid FROM change_records_archive cr INNER JOIN ( SELECT account_id, MAX(InsertDateTime) AS MaxInsertDateTime FROM change_records_archive WHERE change_type = 'Programme' GROUP BY account_id ) t ON cr.account_id = t.account_id AND cr.InsertDateTime = t.MaxInsertDateTime WHERE cr.change_type = 'Programme';
注意:如果同一account_id下有多个记录共享最大时间,这个查询会返回所有符合的记录,和RANK()效果一致。
内容的提问来源于stack exchange,提问作者mrc85
相关产品推荐
相关产品推荐

