SQL中如何移除ID重复但描述不同的重复数据?
处理ID重复但Name不同的数据去重问题
你的数据示例:
| id | name |
|---|---|
| 1 | A |
| 1 | B |
DISTINCT之所以无效,是因为它会判断整行的唯一性——这两行id相同但name不同,属于不同的行,所以会全部返回。以下是两种场景的解决方案:
一、查询时仅保留每个ID的一条记录
1. 使用GROUP BY聚合
通过MIN()或MAX()函数选择每个ID对应的任意一个name,比如取字典序最小的:
SELECT id, MIN(name) AS name FROM your_table GROUP BY id;
如果想取字典序最大的,把MIN()换成MAX()即可。
2. 使用窗口函数(灵活指定保留规则)
适用于MySQL 8+、PostgreSQL、SQL Server等支持窗口函数的数据库,可以自定义保留哪一条(比如按name排序取第一条,或按时间字段取最新的):
WITH ranked_data AS ( SELECT id, name, ROW_NUMBER() OVER (PARTITION BY id ORDER BY name) AS rn FROM your_table ) SELECT id, name FROM ranked_data WHERE rn = 1;
如果表中有时间字段(比如create_time),想保留最新的记录,把ORDER BY name改成ORDER BY create_time DESC即可。
二、删除表中的重复数据(仅保留一条)
1. 窗口函数标记后删除
WITH ranked_data AS ( SELECT id, name, ROW_NUMBER() OVER (PARTITION BY id ORDER BY name) AS rn FROM your_table ) DELETE FROM ranked_data WHERE rn > 1;
注:部分数据库(如MySQL)不支持直接从CTE删除,可改用关联删除:
DELETE t1 FROM your_table t1 JOIN ( SELECT id, name, ROW_NUMBER() OVER (PARTITION BY id ORDER BY name) AS rn FROM your_table ) t2 ON t1.id = t2.id AND t1.name = t2.name WHERE t2.rn > 1;
2. 针对无窗口函数的旧版数据库(如MySQL 5.x)
假设表有自增主键(比如id_col),保留每个ID中主键最小的记录,删除其他重复项:
DELETE t1 FROM your_table t1 JOIN your_table t2 ON t1.id = t2.id AND t1.id_col > t2.id_col;
内容的提问来源于stack exchange,提问作者Carlos Alberto
相关产品推荐
相关产品推荐

