背景
**使用版本:**MySQL 8.2
**使用背景:**现在有一张表 goodsinfo,是另一张表同步过来的数据,但是由于操作不当,插入了多条重复数据,使得 goodsinfo 表有很多尺幅的数据,而且 goodsinfo 没有设置所以也没有设置主键,现在需要将其重复的数据删除,只保留唯一一条数据
goodsinfo 属性如下,有很多重复数据:
- itemunitcode 是同步过来的那张的自增主键,在那张表是不重复的
- tranferin 是同步过来的时间
- cost 是价格
实施
解决思路:
1、创建一个临时表 t2,加一个自增主键字段 id,同步 goodsinfo 表数据进入,然后使用 MySQL8 新增的窗口函数 ROW_NUMBER()
2、将 goodsinfo 数据插入到 t2 中,通过 ROW_NUMBER() 使用 itemunitcode 分组,因为 itemunitcode 应该是唯一值,多个 itemunitcode 就应该删掉只保留一条
3、所以目前只要是 itemunitcode 相同的就会分为一组,然后每组有几条重复的数据,ROW_NUMBER() 就会帮我们计有几条
具体实现:
1、首先创建临时表 ,并插入数据
-- 创建临时表t2
CREATE TABLE t2 LIKE goodsinfo;
-- 增加一列自增主键
ALTER TABLE t2 ADD COLUMN id int PRIMARY KEY auto_increment FIRST;
--插入 goodsuinfo 数据到 t2
INSERT INTO t2(itemunitcode, tranferin, cost) SELECT * FROM goodsinfo;
2、这里创建一个视图 t20 和 t21,使用 ROW_NUMBER() 实现临时查询表
-- 首先创建一个视图只有一条没有重复的数据,不需要处理
CREATE VIEW t20 AS SELECT * FROM t2 WHERE id NOT IN (SELECT id FROM t2 GROUP BY itemunitcode HAVING COUNT(*) = 1);
-- 然后创建视图,通过 itemunitcode 分组,然后每组都给每条分配一个行号
CREATE VIEW t21 AS SELECT id, ROW_NUMBER() over(PARTITION by itemunitcode) as num, itemunitcode, tranferin,cost FROM t20;
SELECT * FROM t21;
3、可以看到,每组都有一个行号,然后我们将每组的行号 num 为 1 的保留,剩下的都是重复的都删除
DELETE FROM t2 WHERE id NOT IN(
SELECT id FROM t21 WHERE num=1
);
以上,就可以把重复的数据删除
总结一下:
1、因为是比较急的时候想出来的,所以大家有什么更好的想法可以分享一下
2、以后不管表的大小,都要设置主键和索引,这样更好进行维护
3、不管如何,记得先备份