【实战篇】一文教你如何删除重复记录

一文教你如何删除重复记录

示例一:根据行号和排序

场景分析:

  • 现以用户表(t_user)为例,uidid 为表中的某个字段。
  • 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);

示例解析:

在这个例子中,内部查询首先为每个 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() 函数的具体用法:

  1. ROW_NUMBER(): 这是一个窗口函数,它会为结果集中的每一行分配一个唯一的序号,序号的分配是连续的,从1开始,不管中间是否有空缺。
  2. OVER: 这个关键字用来指定窗口函数的参数,即定义窗口函数的作用域和排序的顺序。
  3. PARTITION BY uid: 这个子句定义了窗口函数的分区依据。在这里,PARTITION BY 将结果集按照 uid 字段的值进行分组。对于每个 uid 分区,ROW_NUMBER() 都会重新从1开始计数。
  4. ORDER BY id: 这个子句定义了窗口函数内部的排序规则。在这里,它指定了在每个 uid 分区内部,行应该根据 id 字段的值进行升序排序。如果有多条记录具有相同的 id,它们的行号可能会是相同的。
  5. 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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值