首先 假如我们出现了问题数据 有很多值是一样的
比如 我们有一个 学生表 建表sql如下
--创建表
create table tb_student_score(id int,sid int,name varchar2(20),kid int,kname varchar2(20),score int);
--插入数据
insert into tb_student_score values(1,2018001,'张三',0001,'数学',69);
insert into tb_student_score values(2,2018002,'李四',0001,'数学',89);
insert into tb_student_score values(3,2018001,'张三',0001,'数学',69);
insert into tb_student_score values(4,2018002,'李四',0002,'语文',79);
insert into tb_student_score values(5,2018001,'张三',0002,'语文',80);
insert into tb_student_score values(6,2018002,'李四',0002,'语文',79);
commit;
可以看出 除了id外 我们存在一些重复的数据
我们可以使用删除的方式进行删除(数据量不太大的情况下可以使用)
我们可以对除了id外的其他字段进行分组 找出最小的sid然后删除代码如下
DELETE FROM tb_student_score
where id not in (
select min(id)
from tb_student_score
group by sid,name,kid,kname,score
)
假如数据量特别大的话 不建议使用删除的方法 因为会特别的耗时
此时可以采用复制表的策略
首先根据表里的字段 那写数据定位这条数据的唯一性 进行分区 然后 取 第一条 栗子如下:
--首先可以根据字段分区作为唯一标识
select * from (
select t.*,row_number() over(partition by sid,name,kid,kname,score order by sid) as rank
from tb_student_score t
) where rank = 1
--这样子里面的数据就保证没有重复了
--然后可以把这个查询出来的结果放到一个中间表里面去
create table tb_student_score_bak
as
select * from (
select t.*,row_number() over(partition by sid,name,kid,kname,score order by sid) as rank
from tb_student_score t
) where rank = 1
--这样这个中间表里面的数据就是没有重复的了
--然后删除原表 把中间表里面的数据复制到原表里面 就可以了