SQL如何去除表中跨列重复数据 实现双向配对值去重
两列值互换类重复数据的SQL去重实现
核心思路
这类重复的本质是:两列值的组合不区分先后顺序属于同一条记录,去重时只需要把两列值按固定规则(比如小值放前、大值放后)统一排序,让顺序互换的两条记录生成相同的分组键,再基于分组键去重即可。
实现方案
方案1:仅需去重返回两列结果(通用最简写法)
所有支持LEAST()、GREATEST()函数的SQL引擎(MySQL、PostgreSQL、Oracle等)都可以直接用这个写法:
-- 假设表名为your_table,两列名为col_a、col_b SELECT DISTINCT LEAST(col_a, col_b) AS col_a, GREATEST(col_a, col_b) AS col_b FROM your_table;
逻辑说明:LEAST()返回传入参数里的最小值,GREATEST()返回传入参数里的最大值,不管原记录是(1,2)还是(2,1),处理后都会统一输出(1,2),搭配DISTINCT直接得到去重后的结果。
如果使用的SQL引擎不支持上述两个函数(比如部分老版本SQL Server),可以用CASE WHEN实现相同逻辑:
SELECT DISTINCT CASE WHEN col_a < col_b THEN col_a ELSE col_b END AS col_a, CASE WHEN col_a < col_b THEN col_b ELSE col_a END AS col_b FROM your_table;
方案2:需要保留表中其他字段的去重写法
如果表除了这两列还有其他业务字段,需要保留整条记录而不是仅返回两列值,可以用窗口函数分组取第一条的方式实现,支持MySQL8+、PostgreSQL、SQL Server、Hive等所有支持窗口函数的引擎:
WITH pair_ranked AS ( SELECT *, ROW_NUMBER() OVER( PARTITION BY -- 按统一排序后的两列值分组,互换值的记录会分到同一组 LEAST(col_a, col_b), GREATEST(col_a, col_b) -- 自定义每组保留的记录规则,比如按主键id升序保留最早插入的一条 ORDER BY id ) AS rn FROM your_table ) -- 取每组排序后的第一条,就是去重后的结果 SELECT * -- 可按需指定要返回的字段 FROM pair_ranked WHERE rn = 1;
边界说明
如果存在两列值相等的记录(比如(5,5)),上述所有写法都能正常处理,不会出现误判重复、数据丢失的问题。
内容的提问来源于stack exchange,提问作者gourav saini
相关产品推荐
相关产品推荐

