一文教你如何删除重复记录
# 一文教你如何删除重复记录
# 写法一:根据行号和排序
场景分析:
- 现以用户表(
t_user)为例,uid和id为表中的某个字段。 uid是表中的唯一字段,但是因为之前没有加唯一索引,导致内部出现uid重复的数据。- 现在需要加唯一索引,但是需要先删除表中多余的重复的脏数据。
SQL 示例:
以下是一个删除重复记录的示例 SQL 语句,它将为每个 uid 保留具有最小 id 值的记录
DELETE
FROM t_user
WHERE id IN (SELECT id
FROM (SELECT id, uid,
ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id) AS row_num
FROM t_user) AS ranked
WHERE row_num > 1);
1
2
3
4
5
6
7
2
3
4
5
6
7
示例解析:
在这个例子中,内部查询首先为每个 uid 分组内的记录分配了一个行号(row_num),根据 id 字段排序,其中最小的 id 值对应行号 1。然后,外层的 IN 子句用来选择那些行号大于 1 的记录,即重复的记录。最后,DELETE 语句根据 id 删除这些记录。
语法解析:
ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id) AS row_num 是 SQL 中的一个窗口函数(window function)的语法。窗口函数用于在不失去分组的情况下,对分组内的数据进行计算。
这里是 ROW_NUMBER() 函数的具体用法:
ROW_NUMBER(): 这是一个窗口函数,它会为结果集中的每一行分配一个唯一的序号,序号的分配是连续的,从1开始,不管中间是否有空缺。OVER: 这个关键字用来指定窗口函数的参数,即定义窗口函数的作用域和排序的顺序。PARTITION BY uid: 这个子句定义了窗口函数的分区依据。在这里,PARTITION BY将结果集按照uid字段的值进行分组。对于每个uid分区,ROW_NUMBER()都会重新从1开始计数。ORDER BY id: 这个子句定义了窗口函数内部的排序规则。在这里,它指定了在每个uid分区内部,行应该根据id字段的值进行升序排序。如果有多条记录具有相同的id,它们的行号可能会是相同的。AS row_num: 这是给窗口函数的结果指定一个别名,方便在查询的其他部分引用。在这里,行号被命名为row_num。
整个表达式的作用是:对于表 t_user 中的每条记录,根据 uid 进行分组,并在每个分组内根据 id 的升序排列,为每条记录分配一个唯一的行号。
这种语法在处理如去重、分组排序等复杂查询时非常有用。例如,你可以使用这个行号来删除每个 uid 分组内的重复记录,只保留具有最小 id 的记录。
# 写法二:max(id)
场景分析:
- 唯一键(
industry_code) - 需要删除多余的重复数据
SQL 示例:
- 查出最大的 id 编号
- 删除其余数据
- 筛选条件务必加上
update enterprise_register
set deleted = 1
where register_num is null
and id not in (select maxId
from (select max(id) as maxId, industry_code
from enterprise_register
where register_num is null
and deleted = 0
group by industry_code) as t2);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
上次更新: 2025/1/23 18:24:24