You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无唯一列时如何保留重复数据集唯一实例?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的所有字段值完全重复),还有两种更简洁的标准方法:

  1. 使用DISTINCT
    因为同name的所有字段都一致,直接去重即可:
    SELECT DISTINCT name, height, year FROM table_a;
    
  2. 使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:05:00