无唯一列时如何保留重复数据集唯一实例?SQL实现咨询
无唯一键表去重:保留每个
name的单条记录 问题背景
现有table_a表结构及数据如下:
CREATE TABLE table_a ( name INT, height INT, year INT ); INSERT INTO table_a (name, height, year) VALUES (1, 180, 2010), (1, 180, 2010), (1, 180, 2010), (2, 175, 2020), (2, 175, 2020), (3, 150, 2019);
表中存在重复数据,需求是最终结果中每个name仅出现一次,不关心保留哪条记录,预期结果:
name height year 1 180 2010 2 175 2020 3 150 2019
常规的rank()/dense_rank()因为同name的记录排名相同,无法通过rank=1筛选。尝试了以下解法:
select * from ( select *, row_number() over (partition by name order by (select null)) as rn from table_a )g where rn=1;
疑问:这是否是解决此类问题的标准方法?
解答
你用的这个方法是通用且标准的解法之一,尤其适用于「同分组内存在字段差异,且不关心保留哪条记录」的场景:
row_number()会为每个name分组内的记录分配唯一行号,即使没有唯一排序键,order by (select null)会让数据库自行处理排序逻辑(不同数据库实现略有差异,但最终都会生成唯一行号),取rn=1就能得到每组一条记录。- 这个写法在MySQL、PostgreSQL、SQL Server等主流数据库中都兼容,属于通用的无唯一键去重手段。
另外针对你这个场景(同name的所有字段值完全重复),还有两种更简洁的标准方法:
- 使用
DISTINCT
因为同name的所有字段都一致,直接去重即可:SELECT DISTINCT name, height, year FROM table_a; - 使用
GROUP BY
按name分组后,对其他字段取任意聚合函数(因为值都相同,MAX/MIN结果一致):SELECT name, MAX(height) AS height, MAX(year) AS year FROM table_a GROUP BY name;
总结:你的解法是标准通用解法,适合更复杂的分组去重场景;如果是当前这种全字段重复的简单场景,DISTINCT或GROUP BY会更简洁。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

