重复的数据分两种,一种是表中部分字段的重复,一种是两行以上的记录完全一样。
- 部分字段的重复:
查询不重复的数据SQL:
select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) = 1
部分字段重复数据的删除:
查询重复的数据SQL:
select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1
删除上面查询出的重复的数据:
delete from 表名 a where 字段1,字段2 in
(select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
以上即是删除查询到的数据,这种删除执行效率低下,数据量大时,不适合。
另一种方法是先将查询到的重复的数据插入到一张临时表,然后对其进行删除,这样,在执行删除的时候就不用再进行一次查询了。
CREATE TABLE 临时表 AS
(select 字段1,字段2,count(*) from 表名 group by 字段1,字段2 having count(*) > 1)
--建立临时表,并将查询到的数据插入其中。
再进行删除操作:
delete from 表名 a where 字段1,字段2 in (select 字段1,字段2 from 临时表);
这种先建临时表再进行删除的操作要比直接用一条语句进行删除高效得多。
以上是把所有的重复的数据全都删除,没有保留重复数据的其中一条记录。
如何保留重复数据的其中一条记录?
在oracle中,有个隐藏了字段为rowid,表中每条记录都有一个唯一的rowid,
如果想保留最新一条记录,可以利用这个字段,保留重复数据中rowid最大的一条记录就可以了
以下括号中是查询出重复数据中rowid最大的一条记录,括号外是查询出除了rowid最大之外的其他重复的数据:
select a.rowid,a.* from 表名 a
where a.rowid !=
(
select max(b.rowid) from 表名 b
where a.字段1 = b.字段1 and
a.字段2 = b.字段2
)
要删除重复数据,只保留最新的一条数据:
delete from 表名 a
where a.rowid !=
(
select max(b.rowid) from 表名 b
where a.字段1 = b.字段1 and
a.字段2 = b.字段2
)
以上即是删除查询到重复的数据,保留最新一条记录,这种删除执行效率低下,数据量大时,不适合。
考虑建立临时表,将需要判断重复的字段,rowid插入到临时表中,然后删除的时候再进行比较。
create table 临时表 as
select a.字段1,a.字段2,MAX(a.ROWID) dataid from 正式表 a GROUP BY a.字段1,a.字段2;
delete from 表名 a
where a.rowid !=
(
select b.dataid from 临时表 b
where a.字段1 = b.字段1 and
a.字段2 = b.字段2
);
- 完全重复记录的删除:
对于表中两行或以上的记录完全一样的情况,可以使用以下语句获取到去掉重复数据后的记录:
select distinct * from 表名
将查询的记录放进临时表,然后再将原来的表记录删除,最后将临时表的数据导回原来的表中。
CREATE TABLE 临时表 AS (select distinct * from 表名);
truncate table 正式表;
insert into 正式表 (select * from 临时表);
drop table 临时表;