存储优化 - 删除重复记录只保留单条

由于前端提交处理做的不到位或者数据库设计的不够合理,库中通常会存在一些冗余数据,比如重复记录就是一种,那这样的记录如何删除呢?

我们先看一下相关数据结构的知识。

在学习线性表的时候,曾有这样一个例题。

已知一个存储整数的顺序表La,试构造顺序表Lb,要求顺序表Lb中只包含顺序表La中所有值不相同的数据元素。
算法思路:
先把顺序表La的第一个元素付给顺序表Lb,然后从顺序表La的第2个元素起,每一个元素与顺序表Lb中的每一个元素进行比较,如果不相同,则把该元素附加到顺序表Lb的末尾。

 
  
1 public SeqList < int > Purge(SeqList < int > La)
2 {
3 SeqList < int > Lb = new SeqList < int > (La.Maxsize);
4 // 将a表中的第1个数据元素赋给b表
5   Lb.Append(La[ 0 ]);
6 // 依次处理a表中的数据元素
7 for ( int i = 1 ; i <= La.GetLength() - 1 ; ++ i)
8 {
9 int j = 0 ;
10 // 查看b表中有无与a表中相同的数据元素
11 for (j = 0 ; j <= Lb.GetLength() - 1 ; ++ j)
12 {
13 // 有相同的数据元素
14 if (La[i].CompareTo(Lb[j]) == 0 )
15 {
16 break ;
17 }
18 }
19 // 没有相同的数据元素,将a表中的数据元素附加到b表的末尾。
20 if (j > Lb.GetLength() - 1 )
21 {
22 Lb.Append(La[i]);
23 }
24 return Lb;
25 }
26 }

如果理解了这个思路,那么数据库中的处理就好办了。 

我们可以做一个临时表来解决问题

 
  
1 select distinct * into #Tmp from tableName
2 drop table tableName
3 select * into tableName from #Tmp
4 drop table #Tmp

发生这种重复的原因是表设计不周产生的,增加唯一索引列即可解决。

但是你说了,我不想增加任何字段,但这时候又没有显式的标识列,怎么取出标识列呢?(可以是序号列,GUID,等)

上个问题先不讲,先看看这个问题。

我们分别在三种数据库中看一下处理办法,就是通常我们用的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 ( * ) > 1
select * from test group by id
select distinct * from test
delete from test a where a.rowid != ( select max (rowid) from test b where a.id = b.id);

扯远了,回到原来的问题,除了采用数据结构的思想来处理,因为数据库特有的事务处理,能够把数据缓存在线程池里,这样也相当于临时表的功能,所以,我们还可以用游标来解决删除重复记录的问题。

 
  
1 declare @max int ,
2 @id int
3 declare cur_rows cursor local for select id , count ( * ) from test group by id having count ( * ) > 1
4 open cur_rows
5 fetch cur_rows into @id , @max
6 while @@fetch_status = 0
7 begin
8 select @max = @max - 1
9 set rowcount @max -- 让这个时候的行数等于少了一行的统计数
10 delete from test where id = @id
11 fetch cur_rows into @id , @max
12 end
13 close cur_rows
14 set rowcount 0

以上是闪电查阅一些资料写出的想法,有考虑不周的地方,欢迎大家指出。

转载于:https://www.cnblogs.com/levinlee/archive/2010/03/18/1688580.html

01、禁用索引服务 02、禁止window发送错误报告 03、禁用“最近使用的项目” 04、关团Windows Defender 05、关闭防火墙 06、检查更新而不自动下载更新 07、启动电源计划“高性能” 08、调整申源选项 09、禁用休眠(删除休眠文件) 10、开启快速启动 11、调整休眠文件大小 12、转移虚拟内存 13、关闭系统保护 14、关闭用户账户控制<UAC) 15、WindowsToGo启用应用商店 16、关闭计划任务隐藏的自启 17、移除右键菜单SkyDrivePro 18、禁止运行计算机自动维护计划 19、启用.net framework 3.5.1 20、关闭程序兼容性助手 21、禁止一联网就打开浏览器 22、删除6个文件夹(暂失效) 23、显示受保护的系统文件 24、桌面显示“这台电脑” 25、启动IE增强保护模式 26、将临时文件夹移动到非系统盘 27、关闭家庭组 28、延识启动Superfetch服务 29、设置免输密码自动登陆 30、关闭开机画面(GuI引导) 31、关闭IPv6 32、关闭不需要的视觉特效 33、关闭客户体验改善计划 34、隐藏操作中心任务栏托盘 35、关闭自动播放或自动打开U盘 36、设置窗囗超窄边框 37、删除回收站右键固定到开始屏幕 38、直接删除文件不进入回收站 39、关闭smartscreen应用筛选器 40、关机时强制杀后台不等待 41、关闭不必要的视觉动画效果 42、关团程序跳转列表 43、关闭远程协助 44、更改正默认下载目录 45、清理应用商店缓存 46、任务栏显示星期几” 47、设置系统自带戳屏保存到桌面 48、关闭磁盘碎片整理计划 49、禁用系统日志和内存转储 50、禁用疑难解答和系统诊断服务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值