MySQL使用SQL语句查重去重原创
# 前言
在数据库运维过程中,经常会遇到数据重复的问题,比如由于唯一索引调整、程序bug等原因导致的重复数据写入。本文介绍如何使用SQL语句来识别和清理重复数据。
# 查找重复数据的基本思路
查找重复数据的核心思路是:
- 确定用于判断重复的字段组合
- 使用子查询找出重复记录中除了最新记录之外的其他记录
- 可以选择保留最早或最新的记录,通常我们保留最新记录(通过max函数)
# 查找重复数据的SQL模板
点击查看SQL模板
SELECT * FROM
table_name AS ta
WHERE
ta.id <> (
SELECT
max(tb.id)
FROM
table_name AS tb
WHERE
ta.duplicate_column = tb.duplicate_column -- 用于判断重复的字段
);
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
这个模板中:
table_name
是要操作的表名id
是表的主键duplicate_column
是用于判断重复的字段,可以是单个字段,也可以是多个字段的组合
# 实际应用示例
下面是一个更复杂的实际应用示例,展示了如何在特定时间范围内查找多字段组合重复的数据:
点击查看SQL实例
SELECT * FROM
my_test_table_name
WHERE
id IN (
SELECT id
FROM (
SELECT *
FROM my_test_table_name
WHERE updated_at BETWEEN '2022-03-15 18:20:00' AND '2022-03-15 19:30:00'
) AS ta
WHERE ta.id <> (
SELECT max(tb.id)
FROM (
SELECT *
FROM my_test_table_name
WHERE updated_at BETWEEN '2022-03-15 18:20:00' AND '2022-03-15 19:30:00'
) AS tb
WHERE
ta.tran_start_time = tb.tran_start_time
AND ta.tran_end_time = tb.tran_end_time
AND ta.member_account = tb.member_account
)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
这个示例展示了:
- 如何在指定时间范围内查找重复数据
- 如何基于多个字段组合(tran_start_time、tran_end_time、member_account)判断重复
- 如何使用子查询优化查询性能
# 删除重复数据
确认查询结果无误后,可以将 SELECT 语句改写为 DELETE 语句来删除重复数据:
点击查看删除语句
DELETE FROM
my_test_table_name
WHERE
id IN (
SELECT id
FROM (
SELECT *
FROM my_test_table_name
WHERE updated_at BETWEEN '2022-03-15 18:20:00' AND '2022-03-15 19:30:00'
) AS ta
WHERE ta.id <> (
SELECT max(tb.id)
FROM (
SELECT *
FROM my_test_table_name
WHERE updated_at BETWEEN '2022-03-15 18:20:00' AND '2022-03-15 19:30:00'
) AS tb
WHERE
ta.tran_start_time = tb.tran_start_time
AND ta.tran_end_time = tb.tran_end_time
AND ta.member_account = tb.member_account
)
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 注意事项
- 执行删除操作前,强烈建议先使用 SELECT 语句验证查询结果
- 建议在删除前做好数据备份
- 如果数据量较大,建议分批处理,避免长时间锁表
- 删除后检查唯一索引约束,确保不会再次产生重复数据
上次更新: 4/24/2025