高手赐招:如何在表中删除多余的记录? 急!(100分)

  • 主题发起人 主题发起人 piza
  • 开始时间 开始时间
P

piza

Unregistered / Unconfirmed
GUEST, unregistred user!
有一表,如何把表中某一字段内容有重的多余记录删除,只保留其中一条(可以是任意一条)?

比如有字段COL,记录内容如下
A
BB
BB
CC
CC
CC
删除后结果如下
A
BB
CC
如何实现?现用的是ORACLE。



 
添加的时候,首先查询一下,如果不存在就加入不就行了,存在的话就不要加入了!
 
为了清楚, 提问时简化了. 实际要更复杂
表1: F1,F2,F3,F4,FTIME
删除其中的F1,F2分别相等的多余的记录
~~~~

表2: F3,F4,FTIME
删除条件
表2.FTIME界于表1满足条件的两条记录的时间差(条件:表2.F3=表1.F3, 表2.F4=表1.F4)
既在一定时间段内满足条件的记录不能有多余的
 
建议:
建立一个临时表格,用DISTINCT谓词将满足条件的
数据选择出来!
 
用SQL不能解决吗,条件可以设很多嘛
 
delete from table_name where rowid in
(select rowid from table_name where rowid in
( select col from table_name group by col having count(col)>1))
 
look
如何查找、删除表中重复的记录


软件环境:
1、Windows NT4.0+ORACLE 8.0.4
2、ORACLE安装路径为:C:/ORANT

问题提出:
1、当我们想要为一个表创建唯一索引时,如果该表有重复的记录,则无法创建成功。
方法原理:
1、Oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,
  rowid确定了每条记录是在ORACLE中的哪一个数据文件、块、行上。

2、在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中
  那些具有最大rowid的就可以了,其余全部删除。

3、以下语句用到了3项技巧:rowid、子查询、别名。

实现方法:
SQL> create table a (
2 bm char(4), --编码
3 mc varchar2(20) --名称
4 )
5 /

表已建立.

SQL> insert into a values('1111','1111');
SQL> insert into a values('1112','1111');
SQL> insert into a values('1113','1111');
SQL> insert into a values('1114','1111');

SQL> insert into a select * from a;

插入4个记录.

SQL> commit;

完全提交.

SQL> select rowid,bm,mc from a;

ROWID BM MC
------------------ ---- -------
000000D5.0000.0002 1111 1111
000000D5.0001.0002 1112 1111
000000D5.0002.0002 1113 1111
000000D5.0003.0002 1114 1111
000000D5.0004.0002 1111 1111
000000D5.0005.0002 1112 1111
000000D5.0006.0002 1113 1111
000000D5.0007.0002 1114 1111

查询到8记录.


查出重复记录
SQL> select rowid,bm,mc from a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);

ROWID BM MC
------------------ ---- --------------------
000000D5.0000.0002 1111 1111
000000D5.0001.0002 1112 1111
000000D5.0002.0002 1113 1111
000000D5.0003.0002 1114 1111

删除重复记录
SQL> delete from a a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);

删除4个记录.

SQL> select rowid,bm,mc from a;

ROWID BM MC
------------------ ---- --------------------
000000D5.0004.0002 1111 1111
000000D5.0005.0002 1112 1111
000000D5.0006.0002 1113 1111
000000D5.0007.0002 1114 1111


【最后更新:02/27/2001 18:22:58】



 
如果我没跟错程序的话,楼上的这种办法只能删除重复中最大rowid 的哪一条记录。
这也告诉了我们不管你现在用不用。ID字段还是老老实实的加上去为好。
用存储过程做这件事比较好。



 
zhanggeye,有没有看错
delete from a a where a.rowid!=(select max(rowid) from a b where a.bm=b.bm and a.mc=b.mc);

where a.rowid!=(select max(rowid) from ...)
是保留rowid最大的那条,而不是删除重复记录中rowid最大那条!!!!!!!!!!

看一下oracle中rowid的定义,这不是id字段!!!!!!!!!!!!!!!!!!!!!
ROWID是数据行在物理磁盘上的物理地址,Oracle通过ROWID来定位数据的具体位置,这是存取表中数据的最快的方法。


 
A1: 是看错了,我把 != 只看到 =
A2: 我是指在数据库设计时应给表加上ID字段,无论你用什么数据库
 
zhanggeye同志,id字段在oracle中可没有这回事,要用序列来做才行的,不像sql server有increment
字段
要这样才能在oracle中实现id字段
create sequence ab_seq
increment by 1
start with 1
nomaxvalue
nocycle ;

然后在插入数据的时候
insert into abcd values(ab_seq.nextval,'kd',....);
 
我用的不是oracle,但我想oracle中也应该用类似的创建临时表的语法:
我想还是创建临时表简单点,
select distinct... into #temptbl from tablename where condition
然后清除源表中记录,把临时表中的纪录再插入源表。
 
bald_eagle,这么危险的操作你也做得出来,英雄啊!如果清除源表后服务器挂了什么办?
而且你select distinct的时候,数据量不会小到那去吧
所以zhanggeye说的加上一个能自增的字段还是有点用的
 
把这几步操作放在一个交易中。而且只在后台进行。
其实如果真的控制不允许输入重复数据(方法有的是),干吗还要提出这个
问题。
 
honghs 的回答已经对了,为什么还在继续?
 
ggqq,要让别人觉得物有所值,把100分全都给你,当然要.........多说废话啦
 
好吧,先加分!
这几天在解决更难的问题未得其果!!!另加分
 
后退
顶部