SQL中如何对两列存在镜像值的重复行进行去重
两列镜像值去重实现方案
以下是几种常用的实现方式,适配不同场景需求:
通用最简写法(适配绝大多数数据库)
利用LEAST和GREATEST函数将镜像行归为同一类,直接去重即可:
SELECT DISTINCT LEAST(C1, C2) AS C1, GREATEST(C1, C2) AS C2 FROM 你的表名;
原理说明
LEAST(C1, C2)会返回两个字段中更小的值,GREATEST(C1, C2)返回更大的值,所以(A,B)和(B,A)的计算结果完全一致,去重后只会保留一行。如果你的表中本身就存在C1=C2的行也不会受影响。
保留原行顺序写法
如果不需要强制把更小的值放在C1列,想要保留原表中的某一行,可以用窗口函数实现:
WITH ranked_rows AS ( SELECT C1, C2, ROW_NUMBER() OVER( PARTITION BY LEAST(C1, C2), GREATEST(C1, C2) ORDER BY C1 -- 可自行调整排序规则,决定每组保留哪一行 ) AS rn FROM 你的表名 ) SELECT C1, C2 FROM ranked_rows WHERE rn = 1;
低版本数据库兼容写法
如果你的数据库不支持LEAST/GREATEST函数,可以用CASE WHEN替代实现相同逻辑:
SELECT DISTINCT CASE WHEN C1 < C2 THEN C1 ELSE C2 END AS C1, CASE WHEN C1 < C2 THEN C2 ELSE C1 END AS C2 FROM 你的表名;
INNER JOIN实现方式
你猜测的关联写法也可以实现,不过性能略低于上面的方案,参考写法如下:
SELECT DISTINCT t1.C1, t1.C2 FROM 你的表名 t1 INNER JOIN 你的表名 t2 ON t1.C1 = t2.C2 AND t1.C2 = t2.C1 WHERE t1.C1 < t1.C2;
内容的提问来源于stack exchange,提问作者Kevin Sun
相关产品推荐
相关产品推荐

