澳门金沙vip解决Oracle删除重复数据只留一条的方法详解

我们先看一下相关数据结构的知识。 在学习线性表的时候,曾有这样一个例题。
已知一个存储整数的顺序表La,试构造顺序表Lb,要求顺序表Lb中只包含顺序表La中所有值不相同的数据元素。
算法思路:
先把顺序表La的第一个元素付给顺序表Lb,然后从顺序表La的第2个元素起,每一个元素与顺序表Lb中的每一个元素进行比较,如果不相同,则把该元素附加到顺序表Lb的末尾。
复制代码 代码如下: public SeqListint
Purge(SeqListint La) { SeqListint Lb = new SeqListint(La.Maxsize);
//将a表中的第1个数据元素赋给b表 Lb.Append(La[0]);
//依次处理a表中的数据元素 for (int i = 1; i = La.GetLength() – 1; ++i) {
int j = 0; //查看b表中有无与a表中相同的数据元素 for (j = 0; j =
Lb.GetLength() – 1; ++j) { //有相同的数据元素 if
(La[i].CompareTo(Lb[j]) == 0) { break; } }
//没有相同的数据元素,将a表中的数据元素附加到b表的末尾。 if (j
Lb.GetLength() – 1) { Lb.Append(La[i]); } return Lb; } }
如果理解了这个思路,那么数据库中的处理就好办了。
我们可以做一个临时表来解决问题 复制代码
代码如下: select distinct * into #Tmp from tableName drop table
tableName select * into tableName from #Tmp drop table #Tmp
发生这种重复的原因是表设计不周产生的,增加唯一索引列即可解决。
但是你说了,我不想增加任何字段,但这时候又没有显式的标识列,怎么取出标识列呢?
上个问题先不讲,先看看这个问题。
我们分别在三种数据库中看一下处理办法,就是通常我们用的Sqlserver2000,Sqlserver2005,Oracle
10g. 1. SQL Server 2000 构造序号列 方法一: SELECT 序号= (SELECT
COUNT(客户编号) FROM 客户 AS a WHERE a.客户编号= b.客户编号),
客户编号,公司名称 FROM 客户 AS b ORDER BY 1; 方法二: SELECT 序号=
COUNT(*), a.客户编号, a.公司名称FROM 客户 AS a, 客户 AS b WHERE
a.客户编号= b.客户编号 GROUP BY a.客户编号, b.公司名称 ORDER BY 序号;
2. SQL Server 2005 构造序号列 方法一: SELECT RANK() OVER (ORDER BY
客户编号 DESC) AS 序号, 客户编号,公司名称 FROM 客户; 方法二: WITH TABLE
AS (SELECT ROW_NUMBER() OVER (ORDER BY 客户编号 DESC) AS 序号,
客户编号,公司名称 FROM 客户) SELECT * FROM TABLE WHERE 序号 BETWEEN 1
AND 3;3. Oracle 里 rowid 也可看做默认标识列
在Oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,rowid确定了每条记录是在Oracle中的哪一个数据文件、块、行上。
在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中那些具有最大rowid的就可以了,其余全部删除。
复制代码 代码如下: select * from
test;select * from test group by id having count(*)1select * from
test group by idselect distinct * from testdelete from test a where
a.rowid!=(select max(rowid) from test b where
a.id=b.id);扯远了,回到原来的问题,除了采用数据结构的思想来处理,因为数据库特有的事务处理,能够把数据缓存在线程池里,这样也相当于临时表的功能,所以,我们还可以用游标来解决删除重复记录的问题。
declare @max int, @id int declare cur_rows cursor local for select id
,count(*) from test group by id having count(*) 1 open cur_rows fetch
cur_rows into @id ,@max while @@fetch_status=0 begin select @max =
@max -1 set rowcount @max
–让这个时候的行数等于少了一行的统计数,想想看,为什么 delete from test
where id = @id fetch cur_rows into @id ,@max end close cur_rows set
rowcount 0
以上是闪电查阅一些资料写出的想法,有考虑不周的地方,欢迎大家指出。

查询及删除重复记录的SQL语句
1、查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断
select * from 表 where  Id in (select Id from 表 group by Id having
count(Id) > 1)

2、删除表中多余的重复记录,重复记录是根据单个字段(Id)来判断,只留有rowid最小的记录 DELETE from 表 WHERE (id) IN ( SELECT id FROM 表 GROUP BY id HAVING
COUNT(id) > 1) AND ROWID NOT IN (SELECT MIN(ROWID) FROM 表 GROUP BY
id HAVING COUNT(*) > 1);

3、查找表中多余的重复记录(多个字段) select * from 表 a
where (a.Id,a.seq) in (select Id,seq from 表 group by Id,seq having
count(*) > 1)
4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录 delete from 表 a
where (a.Id,a.seq) in   (select Id,seq from 表 group by Id,seq having
count(*) > 1)
and rowid not in (select min(rowid) from 表 group by Id,seq having
count(*)>1)
5、查找表中多余的重复记录(多个字段),不包含rowid最小的记录 select * from 表 a
where (a.Id,a.seq) in   (select Id,seq from 表 group by Id,seq having
count(*) > 1)
and rowid not in (select min(rowid) from 表 group by Id,seq having
count(*)>1)

(二) 比方说
在A表中存在一个字段“name”,
而且不同记录之间的“name”值有可能会相同,
现在就是需要查询出在该表中的各记录之间,“name”值存在重复的项;
Select Name,Count(*) From A Group By Name Having Count(*) > 1
如果还查性别也相同大则如下:
Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) >
1
(三)
方法一
复制代码 代码如下:
declare @max integer,@id integer
declare cur_rows cursor local for select 主字段,count(*) from 表名
group by 主字段 having count(*) >; 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id,@max
end
close cur_rows