MySQL单表删除重复列

本贴最后更新于 3189 天前,其中的信息可能已经时移世异

这其实是一个面试题,但是我没答上来。(≧﹏ ≦)

 

一、需求

有一张表,数据类似于:

id        name

1         x

2         x

3         y

4         z

5         z

 

要求删除name重复的记录,只留下同名的第一条

 

二、解决

1. 先创建表、测试数据

CREATE TABLE `test` (
  `id` int(10) NOT NULL DEFAULT '0',
  `name` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

insert into test values(1, 'zhangsan'), (2, 'zhangsan'), (3, 'lisi'), (4, 'wangwu'), (5, 'wangwu'), (6, 'wangwu'), (7, 'zhaoliu'), (8, 'zhaoliu'), (9, 'jack'), (10, 'rose');

 

数据如下

mysql> select * from test;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | zhangsan |
|  3 | lisi     |
|  4 | wangwu   |
|  5 | wangwu   |
|  6 | wangwu   |
|  7 | zhaoliu  |
|  8 | zhaoliu  |
|  9 | jack     |
| 10 | rose     |
+----+----------+
10 rows in set (0.00 sec)

 

 

2. SQL

方法1:多表delete语法

mysql>  DELETE ta FROM test ta,test tb where ta.name=tb.name and ta.id>tb.id;
Query OK, 4 rows affected (0.05 sec)

mysql> select * from test;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 3 | lisi |
| 4 | wangwu |
| 7 | zhaoliu |
| 9 | jack |
| 10 | rose |
+----+----------+
6 rows in set (0.00 sec)

 

方法2:中间表的方式

create table test_tmp like test;

insert into test_tmp select min(id), name from test group by name;

drop table test;

rename table test_tmp to test;

 

方法n

其实还有其他的方法,比如说:

  • 新建test_tmp,在name字段上添加唯一索引,然后,用insert ignore into方法。
  • 导出到文件,然后在加载回来的过程中去重。参考:imysql.cn/node/222

 

暂时不知道几种方法在性能上的优缺点

 

3. 什么方法不行

mysql> delete from test where id not in (select min(id) as id from test group by name);


ERROR 1093 (HY000): You can't specify target table 'test' for update in FROM clause

不支持此语法!虽然这是我第一个想到的方法,我的MySQL是5.6.23版本的





  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    325 引用 • 1395 回帖 • 1 关注
  • SQL
    127 引用 • 386 回帖 • 3 关注
  • Test

    如果你要试验论坛功能,请到 Sandbox 标签下发帖。

    14 引用 • 29 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • yangyujiao

    第一种方法如果没有 id 从小到大那种排序是不是就不行了。我们的数据库都是存 uuid,没有 id。