重复记录的处理

[复制链接]
查看11 | 回复9 | 2012-5-15 15:24:11 | 显示全部楼层 |阅读模式
重复记录,只保留一条。
没有想到可以用minus轻松解决
(出差偶得)


回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
可否把具体的情况说明一下,好让大家分享呀。


回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
回公司再整理一下。
回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
期待中……
回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
可以有三种方法: 1.自连接查询. select rowid ,name from test a where rowid>(select min(rowid) from test b wherea.name= b.name )
2. 分组查询: select count(*), name from test group by name having count(*) >1;
3.exceptioin 处理: 创建EXCEPTIONS table,然后建一个唯一性索引,连接TEST表和EXCEPTIONS表,就可得出所有重复记录.
回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
是不是这样?
假设table1是包含重复键值key=key1的表
delete table1 where rowid in
(select rowid
from table1where key=key1
minus
select min(rowid) from table1where key=key1);
回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
用户系统迁移,同事经验不足,作了数次imp,导致数据库中没有主键的表的数据重复多次。
而且系统已经运行一周了,不可能重复导数据库。涉及6个用户,500多个表。
create table test
(a varchar2(10),
b char(10),
c number,
d date
);
create table test_tmp as
select * from test
minus
select '0','0',0,to_date(null) from dual;
truncate table test;
insert into test select * from test_tmp;
commit;
drop table tmp;
注:
minus后面的sql,可以有下面的函数生成。
SQL> selectf_getcolumns('test') from dual;
F_GETCOLUMNS('TEST')
--------------------------------------------------------------------------------
'0','0',0,to_date(null)
CREATE OR REPLACE function f_getcolumns
(sourceIN VARCHAR2)
return VARCHAR2
as
id_var
VARCHAR2(30);
--name_var VARCHAR2(30);
source_cursorINTEGER;
ignore
INTEGER;
ls_tmp
VARCHAR2(4000);
ls_tmp0
VARCHAR2(30);
BEGIN
ls_tmp := '';
source_cursor := dbms_sql.open_cursor;
DBMS_SQL.PARSE(source_cursor,
'SELECT DATA_TYPE FROM user_tab_columns where lower(TABLE_NAME)=lower('||''''|| source||''''||')',

DBMS_SQL.native);
DBMS_SQL.DEFINE_COLUMN(source_cursor,1,id_var,30);
ignore := DBMS_SQL.EXECUTE(source_cursor);
LOOP
IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN
DBMS_SQL.COLUMN_VALUE(source_cursor,1,id_var);
if id_var in ('VARCHAR2','CHAR') then

ls_tmp0:=''''||'0'||'''';
elsif id_var in ('NUMBER') then

ls_tmp0:='0';
elsif id_var = ('DATE') then

ls_tmp0:='to_date(null)';

end if;
ls_tmp := ls_tmp||ls_tmp0||',';
ELSE
EXIT;
END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(source_cursor);
return substr(ls_tmp,1,length(ls_tmp) - 1);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(source_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(source_cursor);
return 'hello';
END IF;
RAISE;
END;
/
:该函数可能要根据实际情况稍加改动
:对于含有long,long raw,lob等类型的表,需要特殊处理,也很简单。
回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
需要熟悉表结果,知道哪几个字段来判断数据重复。
最初由 fugang 发布
[B]可以有三种方法: 1.自连接查询. select rowid ,name from test a where rowid>(select min(rowid) from test b wherea.name= b.name )
2. 分组查询: select count(*), name from test group by name having count(*) >1;
3.exceptioin 处理: 创建EXCEPTIONS table,然后建一个唯一性索引,连接TEST表和EXCEPTIONS表,就可得出所有重复记录. [/B]

回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
问题同上。
最初由 sir.liang 发布
[B]是不是这样?
假设table1是包含重复键值key=key1的表
delete table1 where rowid in
(select rowid
from table1where key=key1
minus
select min(rowid) from table1where key=key1); [/B]

回复

使用道具 举报

千问 | 2012-5-15 15:24:11 | 显示全部楼层
与下面的方法有什么区别吗?
create table .. as select distinct *from ..
truncate table ..
insert into ... select ...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行