Oracle SQL如何基于单个指定列过滤重复行并保留所有列数据
实现单列重复值整行过滤的正确SQL写法
你的核心需求是过滤掉COL_A列存在重复取值的所有整行数据,保留COL_A取值唯一的行的全部字段,之前用的DISTINCT、普通GROUP BY仅能返回COL_A的去重列值,不会筛掉重复取值对应的行,因此不符合要求。
可用实现方案
方案1:窗口函数写法(主流数据库通用,推荐)
支持MySQL 8.0+、PostgreSQL、SQL Server、Oracle等所有支持窗口函数的数据库,逻辑清晰易维护:
SELECT COL_A, COL_B, COL_C FROM ( SELECT *, COUNT(*) OVER (PARTITION BY COL_A) AS row_cnt FROM TBL ) AS t WHERE row_cnt = 1;
逻辑说明:通过PARTITION BY COL_A按COL_A值分区计数,统计每个COL_A值在表中出现的总次数,最终只保留计数为1(即取值唯一)的行,所有原字段都会完整保留。
方案2:子查询关联写法(兼容低版本数据库)
如果使用不支持窗口函数的老版本数据库(比如MySQL 5.x),可以用分组+关联的写法实现:
SELECT t.* FROM TBL t INNER JOIN ( SELECT COL_A FROM TBL GROUP BY COL_A HAVING COUNT(*) = 1 ) AS tmp ON t.COL_A = tmp.COL_A;
逻辑说明:先通过子查询筛选出所有仅出现1次的COL_A值,再通过内连接关联原表,取出这些COL_A对应的完整行数据。
原有写法的问题说明
SELECT DISTINCT COL_A FROM TBL:仅会对返回结果中的COL_A值做去重,不管该值在原表中出现多少次,只要存在就会返回一次,因此会返回出现2次的COL_A=3。SELECT COL_A FROM TBL GROUP BY COL_A:仅按COL_A分组返回每个组的COL_A值,默认不会过滤掉存在多行的分组,因此同样会返回COL_A=3。
内容的提问来源于stack exchange,提问作者Collin Williams
相关产品推荐
相关产品推荐

