如何将数据表中同一ID的不同Name字段值统一为同一值?
需求描述
我有一张数据表,部分ID对应的Name字段存在不同值,示例输入表如下:
| ID | Name | col_3 | col_4 |
|---|---|---|---|
| 1 | name_1 | x_1 | y_1 |
| 2 | name_2 | x_2 | y_2 |
| 3 | name_3 | x_3 | y_3 |
| 4 | name_4 | x_4 | y_4 |
| 1 | other_name_1 | x_5 | y_5 |
| 2 | other_name_2 | x_6 | y_6 |
| 5 | name_5 | x_7 | y_7 |
需要将同一ID下的Name统一,选择哪个值无关紧要,只要同一ID的Name一致即可,期望输出如下:
| ID | Name | col_3 | col_4 |
|---|---|---|---|
| 1 | name_1 | x_1 | y_1 |
| 2 | name_2 | x_2 | y_2 |
| 3 | name_3 | x_3 | y_3 |
| 4 | name_4 | x_4 | y_4 |
| 1 | name_1 | x_5 | y_5 |
| 2 | name_2 | x_6 | y_6 |
| 5 | name_5 | x_7 | y_7 |
解决方案
方法1:窗口函数FIRST_VALUE(推荐,适用于支持窗口函数的数据库)
大多数现代数据库(MySQL 8+、PostgreSQL、SQL Server等)都支持窗口函数,用FIRST_VALUE可以直接为每个ID取分组内第一条记录的Name:
SELECT ID, FIRST_VALUE(Name) OVER (PARTITION BY ID ORDER BY col_3) AS Name, col_3, col_4 FROM your_table;
PARTITION BY ID:按ID将数据分组ORDER BY col_3:指定分组内的排序规则,决定取哪条记录的Name(如果不在乎具体取哪个,部分数据库可以写ORDER BY (SELECT NULL),或者按你需要的字段调整)- 最终同一ID的所有记录都会使用分组内第一条的Name值
方法2:聚合函数+关联子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以先通过聚合函数为每个ID确定一个统一的Name,再关联原表:
SELECT t.ID, agg.Name, t.col_3, t.col_4 FROM your_table t INNER JOIN ( SELECT ID, MIN(Name) AS Name FROM your_table GROUP BY ID ) agg ON t.ID = agg.ID;
- 这里用
MIN(Name)取每个ID下字典序最小的Name,换成MAX(Name)也可以,只要能保证同一ID返回唯一的Name即可
方法3:窗口函数ROW_NUMBER()(灵活指定保留的Name)
如果需要手动指定保留某条特定记录的Name(比如最早创建的记录),可以用ROW_NUMBER()先给每个ID的记录编号,再关联取目标Name:
WITH ranked_data AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY col_3) AS rn FROM your_table ) SELECT rd.ID, (SELECT Name FROM ranked_data WHERE ID = rd.ID AND rn = 1) AS Name, rd.col_3, rd.col_4 FROM ranked_data rd;
ROW_NUMBER()为每个ID的记录按指定规则编号,这里按col_3排序,编号为1的就是要保留Name的记录,调整ORDER BY字段可以选择不同的基准记录
内容的提问来源于stack exchange,提问作者DanteeChaos
相关产品推荐
相关产品推荐

