删除重复数据

在数据库中出现重复数据是常见之事,本文主要介绍如何删除表中的重复数据。

利用主键删除

任务描述

本关任务:按照要求删除表中重复用户。

相关知识

在工作或平时练习中,我们会发现表中经常有重复数据,分情况我们可能需要这些重复数据,也可能不需要这些数据,那么我们该如何找出这些不需要的重复数据并删除呢?

重复数据

下面我们来看一组数据,users表结构及数据如下:

id(主键) user_name user_pwd
1 user1 123
2 user2 456
3 user3 789
4 user1 111
5 user1 222
6 user1 333

上面users表中出现了相同用户名的重复数据,我们需要将其重复的删除,首先我们将重复用户查出来:

找到重复的用户后我们要怎么删除呢?又要怎么选择保留的数据呢?

解题思路

假设我们要保留的数据为先注册的账号,我们可将思路拟定如下:

  • 确定了保留先注册的账号,也就等同保留的数据为id较小的,我们可利用 聚合函数 得到重复数据中的最小id用户;
  • 使用表关联,将重复数据中最小id用户与源users表中的id进行对比,删除users表中id比重复数据中的最小id 的记录,删除后表中的数据就是先注册用户的数据了。

编程要求

请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

  • users表中重复数据去除,保留先注册的账号。(你只需要删除表中重复数据即可,平台将为你查询表中数据)。

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

预期输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
+----+-----------+----------+
| id | user_name | user_pwd |
+----+-----------+----------+
| 1 | user2 | 972 |
| 2 | user5 | 984 |
| 4 | user7 | 474 |
| 5 | user9 | 312 |
| 7 | user3 | 840 |
| 8 | user4 | 485 |
| 11 | user1 | 570 |
| 12 | user6 | 164 |
| 14 | user8 | 884 |
+----+-----------+----------+

我的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#请在此添加实现代码
########## Begin ##########
delete from users where id in (
select * from(
select id from users where user_name
in(
select user_name from users group by user_name having count(1)>1
)
and id not in(
select min(id) from users group by user_name having count(1)>1
)
)as user_repeat_copy
);


########## End ##########

复杂重复数据删除

任务描述

本关任务:删除表中mobile列出现的重复电话号码。

相关知识

在上一章节中我们已经解决了去除简单的重复数据,那如果表中的重复数据是组合的复杂数据呢?我们又该如何解决?

重复数据

下面我们继续看一组数据,仍用上一章节的users表,现在多一列mobile数据:

id(主键) user_name user_pwd mobile
1 user1 123 18212345678,18201234567,18212345678
2 user2 456 18266666666,18288888888
3 user3 789 18268686868,18278787878,18268686868,18278787878

解题思路

看到mobile列中的数据是不是很亲切,在之前学习 行列转换 时我们见过了。

遇到这种情况要将数据去重,我们的解题思路基本就可以拟定为把数据拆开后去重再将数据重新组合。

下面我们细分成几个小步骤来看:

  • 统计mobile列中各用户的电话数量;

  • 拆分数据(连接序列化表);

  • 截取数据;

  • 最后一步我们只需要将数据去重,然后再分组进行组合就大功告成了。

编程要求

请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:
根据解题思路的步骤完成去除users表中mobile列的重复电话号码。(你只需要删除表中重复数据即可,如mobile列数据为18212345678,18201234567,18212345678,去除重复数据之后的数据为18212345678,18201234567。)

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

预期输出:

1
2
3
4
5
6
7
8
9
10
+-------------+---------+
| mob | len |
+-------------+---------+
| 18201234567 | 23.0000 |
| 18212345678 | 23.0000 |
| 18266666666 | 23.0000 |
| 18268686868 | 23.0000 |
| 18278787878 | 23.0000 |
| 18288888888 | 23.0000 |
+-------------+---------+

mob 列为将mobile列所有号码升序输出的结果,len 列为号码所在行的mobile列长度

我的代码

1
2
3
4
5
6
7
8
9
10
11
12
#请在此添加实现代码
########## Begin ##########

update users b join (
select user_name,group_concat(
distinct SUBSTRING_INDEX(SUBSTRING_INDEX(mobile,',',t.id),',',-1)
) mobile from (
select user_name,mobile,length(concat(mobile,','))-length(replace(mobile,',','')) size from users
) a inner join tb_sequence t on a.size>=t.id group by a.user_name
) c on b.user_name = c.user_name set b.mobile = c.mobile;

########## End ##########