在SQL中删除重复记录

sql 有一段 时间 了, 发现 在我建了一个用来 测试 的表(没有建索引)中出 多的重 复记录 。后来 总结 了一些 除重 复记录 的方法,在 Oracle 中,可以通 唯一 rowid 实现删 除重 复记录 可以建 临时 表来 实现 ... 个只提到其中的几 种简单实 用的方法,希望可以和大家分享(以表 employee 例)。

SQL> desc employee
Name Null? Type
----------------------------------------- -------- ------------------
emp_id NUMBER(10)
emp_name VARCHAR2(20)
salary NUMBER(10,2)

可以通 下面的 查询 记录

SQL> select * from employee;
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
1 sunshine 10000
2 semon 20000
2 semon 20000
3 xyz 30000
2 semon 20000

SQL> select distinct * from employee;
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
2 semon 20000
3 xyz 30000
SQL> select * from employee group by emp_id,emp_name,salary having count (*)>1
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
2 semon 20000
SQL> select * from employee e1
where rowid in (select max(rowid) from employe e2
where e1.emp_id=e2.emp_id and
e1.emp_name=e2.emp_name and e1.salary=e2.salary);
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
3 xyz 30000
2 semon 20000
2.
除的几 方法:
1 )通 建立 临时 表来 实现
SQL>create table temp_emp as (select distinct * from employee)

SQL> truncate table employee; (
清空 employee 表的数据)

SQL> insert into employee select * from temp_emp; (
再将 临时 表里的内容插回来)

( 2
)通 唯一 rowid 实现删 除重 复记录 . Oracle 中, 一条 记录 都有一个 rowid rowid 在整个数据 中是唯一的, rowid 确定了 记录 是在 Oracle 中的哪一个数据文件、 、行上。 在重 记录 中,可能所有列的内容都相同,但 rowid 不会相同,所以只要确定出重 复记录 中那些具有最大或最小 rowid 的就可以了,其余全部 除。

SQL>delete from employee e2 where rowid not in (
select max(e1.rowid) from employee e1 where
e1.emp_id=e2.emp_id and e1.emp_name=e2.emp_name and e1.salary=e2.salary);--
里用 min(rowid) 也可以。

SQL>delete from employee e2 where rowid <(
select max(e1.rowid) from employee e1 where
e1.emp_id=e2.emp_id and e1.emp_name=e2.emp_name and
e1.salary=e2.salary);

3 )也是通 rowid ,但效率更高。

SQL>delete from employee where rowid not in (
select max(t1.rowid) from employee t1 group by
t1.emp_id,t1.emp_name,t1.salary);--
里用 min(rowid) 也可以。

EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
3 xyz 30000
2 semon 20000
SQL> desc employee

Name Null? Type
----------------------------------------- -------- ------------------
emp_id NUMBER(10)
emp_name VARCHAR2(20)
salary NUMBER(10,2)

可以通 下面的 查询 记录
SQL> select * from employee;
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
1 sunshine 10000
2 semon 20000
2 semon 20000
3 xyz 30000
2 semon 20000

SQL> select distinct * from employee;
EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
2 semon 20000
3 xyz 30000

SQL> select * from employee group by emp_id,emp_name,salary having count (*)>1

EMP_ID EMP_NAME SALARY
---------- ---------------------------------------- ----------
1 sunshine 10000
2 semon 20000
SQL> select * from employee e1

where rowid in (select max(rowid) from employe e2
where e1.emp_id=e2.emp_id and











CREATE PROCEDURE [K_FIND_CF] --
此存 储过 程用于 找表中的重 2005-07-18 完成
AS

if exists (select * from sysobjects where id = object_id(N'[dbo].[T_find]')
and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[T_find]

CREATE TABLE [dbo].[T_find] (
[cfz] [char](16)
)
select * from GJ_JBXX order by gjbh ------
修改 成你要找的表名和字段名

declare sum1 scroll cursor
for
select count(*) from GJ_JBXX ------
修改 成你要找的表名
open sum1
declare @zshu int
fetch first from sum1 into @zshu
close sum1
deallocate sum1

declare find1 scroll cursor
for
select gjbh from GJ_JBXX ------
修改 成你要找的表名和字段名
open find1

declare find2 scroll cursor
for --update --
指定游 标结 果集可以被修改
select gjbh from GJ_JBXX -------
修改 成你要找的表名和字段名
open find2

declare @yb1 char(16)
declare @yb2 char(16)
fetch first from find2 into @yb2

while(@@fetch_status<>-1) --if @@fetch_status
当前所指的行)在最后一行 @@fetch_status 值为 -1 ,其它情况都 0
begin
fetch next from find1 into @yb1
fetch next from find2 into @yb2
if (@yb1=@yb2) and (@@fetch_status<>-1) --
一句,否 最后一条 记录 认为 是重
insert into dbo.T_find(cfz) values(@yb2)

end
close find1
deallocate find1
close find2
deallocate find2
select * from T_find
GO

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值