SQL查询:如何仅保留排序后前2个不同Random_ID的对应行?
可行实现方案(基于SQL窗口函数)
核心逻辑
- 先定位每个
Random_ID按UN_ID_DATE降序排序后的首次出现行 - 对所有
Random_ID的首次出现行按日期降序取前2个ID - 关联原始结果集,返回这2个ID的全部行
通用SQL实现(适配主流数据库)
-- 替换下方注释标记的「你的结果集/表名」为实际的表名或现有查询的子查询 WITH random_id_first_occur AS ( SELECT *, -- 给同一Random_ID的行按日期降序编号,rn=1即为该ID最早出现的行 ROW_NUMBER() OVER (PARTITION BY Random_ID ORDER BY UN_ID_DATE DESC) AS row_rank FROM 你的结果集/表名 ), top2_unique_random AS ( -- 仅保留每个Random_ID的首次出现行,按日期降序取前2个ID SELECT Random_ID FROM random_id_first_occur WHERE row_rank = 1 ORDER BY UN_ID_DATE DESC LIMIT 2 -- SQL Server可替换为 SELECT TOP 2 ... ) -- 关联取这2个ID的所有行 SELECT 原始结果集.* FROM 你的结果集/表名 原始结果集 INNER JOIN top2_unique_random ON 原始结果集.Random_ID = top2_unique_random.Random_ID -- 可选排序:匹配示例的输出顺序(先按Random_ID降序,再按日期降序) ORDER BY 原始结果集.Random_ID DESC, 原始结果集.UN_ID_DATE DESC;
示例验证
对应给出的样例数据:
- 排序后第一个出现的
Random_ID为9999999,第二个新出现的为4444444 - 筛选后返回所有属于这两个ID的5行数据,和预期结果完全一致
注意事项
- 若原始数据为查询生成的临时结果集,可直接将
你的结果集/表名替换为现有查询的子查询(用括号包裹) - 若存在
UN_ID_DATE完全相同的并行行,可在窗口函数的ORDER BY后添加次级排序字段(如UN_ID)避免排名随机 - 部分数据库(如Oracle)需将
LIMIT 2替换为FETCH FIRST 2 ROWS ONLY
内容的提问来源于stack exchange,提问作者Péter Nagy
相关产品推荐
相关产品推荐

