使用子查询去除重复ID:SQL多表去重关联实现需求
实现按规则关联两张表并得到ID3唯一的结果集
原始表结构与数据
Table 1(ID1唯一,ID2存在重复)
ID1 | ID2 1 | 1 2 | 2 3 | 3 4 | 3 5 | 4 6 | 5 7 | 5 8 | 6 9 | 7 10 | 6
Table 2(ID2唯一,ID3存在重复)
ID2 | ID3 1 | 1 2 | 1 3 | 2 4 | 3 5 | 2 6 | 4 7 | 5
需求目标
最终生成每个ID3唯一的结果集,包含ID1、ID2、ID3三个字段,需遵循以下规则:
- 对Table 1去重:每个ID2保留对应的最大ID1
- 对Table 2去重:每个ID3保留对应的最大ID2
- 关联上述两个处理后的表,得到最终结果
解决方案
方法1:使用窗口函数(推荐,兼容多数现代数据库)
通过CTE(公共表表达式)分步处理两张表,再关联得到结果:
WITH processed_table1 AS ( -- 处理Table1:保留每个ID2的最大ID1 SELECT ID1, ID2 FROM ( SELECT ID1, ID2, -- 按ID2分组,ID1降序排序,每组标记行号 ROW_NUMBER() OVER (PARTITION BY ID2 ORDER BY ID1 DESC) AS rn FROM Table1 ) t WHERE rn = 1 -- 取每组第一行(最大ID1) ), processed_table2 AS ( -- 处理Table2:保留每个ID3的最大ID2 SELECT ID2, ID3 FROM ( SELECT ID2, ID3, -- 按ID3分组,ID2降序排序,每组标记行号 ROW_NUMBER() OVER (PARTITION BY ID3 ORDER BY ID2 DESC) AS rn FROM Table2 ) t WHERE rn = 1 -- 取每组第一行(最大ID2) ) -- 关联两个处理后的表,得到最终结果 SELECT pt1.ID1, pt2.ID2, pt2.ID3 FROM processed_table2 pt2 JOIN processed_table1 pt1 ON pt2.ID2 = pt1.ID2 ORDER BY pt2.ID3;
执行后得到的结果与预期一致:
ID1 | ID2 | ID3 2 | 2 | 1 7 | 5 | 2 5 | 4 | 3 10 | 6 | 4 9 | 7 | 5
方法2:使用子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数,可以用子查询实现相同逻辑:
SELECT pt1.ID1, pt2.ID2, pt2.ID3 FROM ( -- 处理Table2:筛选每个ID3对应的最大ID2 SELECT t2.ID2, t2.ID3 FROM Table2 t2 WHERE t2.ID2 = (SELECT MAX(ID2) FROM Table2 WHERE ID3 = t2.ID3) ) pt2 JOIN ( -- 处理Table1:筛选每个ID2对应的最大ID1 SELECT t1.ID1, t1.ID2 FROM Table1 t1 WHERE t1.ID1 = (SELECT MAX(ID1) FROM Table1 WHERE ID2 = t1.ID2) ) pt1 ON pt2.ID2 = pt1.ID2 ORDER BY pt2.ID3;
说明
- 两种方法核心逻辑一致:先分别过滤出符合要求的中间结果,再通过
ID2关联得到最终的ID3唯一结果集 - 窗口函数写法更清晰易读,数据量大时性能更优
内容的提问来源于stack exchange,提问作者RIzz
相关产品推荐
相关产品推荐

