Oracle删除重复记录只保留一条数据的几种方法
1. 问题描述
BBSCOMMENT表为BBSDETAIL的从表,记录商户评价信息。因为数据倒腾来倒腾去的,有很多重复数据。表结构如下:
COMMENT_ID NOT NULL NUMBER --主键
DETAIL_ID NOT NULL NUMBER --外键,引用BBSDETAIL表
COMMENT_BODY NOT NULL VARCHAR2(500) --评价内容
--其它字段忽略
其中主键是没有重复的,重复的是DETAIL_ID+COMMENT_BODY+......等信息,就是某些商家的评价信息有重复。
2. 解决步骤
2.1 查找表中多余的重复记录
--查询出所有有重复的数据
select DETAIL_ID,COMMENT_BODY,count(*)
from BBSCOMMENT
group by DETAIL_ID,COMMENT_BODY
having count(*)>1
order by DETAIL_ID, COMMENT_BODY; --1955条
2.2 显示了所有的非冗余的数据
--这一条命令显示了所有的非冗余的数据
select min(COMMENT_ID) as COMMENT_ID,DETAIL_ID,COMMENT_BODY
from BBSCOMMENT
group by DETAIL_ID,COMMENT_BODY; --21453条,之所以此值不等于表总记录数-1955,是因为1955条记录中,有的重复了不止一次。
2.3 如果记录数量少(千级别),可以把上面的语句做成子查询然后直接删除
--如果表数据量不是很大(1千条以内),可以把上面的语句做成子查询然后直接删除
delete from BBSCOMMENT where COMMENT_ID not in(
select min(COMMENT_ID)
from BBSCOMMENT
group by DETAIL_ID,COMMENT_BODY
); --782秒,在我这里,2万条记录,重复记录2千多(太慢了!!)
2.4 另一种删除方法
--这条语句也能够实现上述功能,但不好测试了,数据已经被我删除了
--删除条件一:有重复数据的记录;条件二:保留最小rowid的记录。
delete from BBSCOMMENT a
where
(a.DETAIL_ID,a.COMMENT_BODY) in(select DETAIL_ID,COMMENT_BODY from BBSCOMMENT group by DETAIL_ID,COMMENT_BODY having count(*) > 1)
and rowid not in (select min(rowid) from BBSCOMMENT group by DETAIL_ID,COMMENT_BODY having count(*)>1);
2.5 大数据量还是用PL/SQL方便快捷
declare
--定义存储结构
type bbscomment_type is record
(
comment_id BBSCOMMENT.COMMENT_ID%type,
detail_id BBSCOMMENT.DETAIL_ID%type,
comment_body BBSCOMMENT.COMMENT_BODY%type
);
bbscomment_record bbscomment_type; --可供比较的变量
v_comment_id BBSCOMMENT.COMMENT_ID%type;
v_detail_id BBSCOMMENT.DETAIL_ID%type;
v_comment_body BBSCOMMENT.COMMENT_BODY%type; --其它变量
v_batch_size integer := 5000;
v_counter integer := 0; cursor cur_dupl is
--取出所有有重复的记录
select COMMENT_ID, DETAIL_ID, COMMENT_BODY
from BBSCOMMENT
where(DETAIL_ID, COMMENT_BODY) in (
--这些记录有重复
select DETAIL_ID, COMMENT_BODY
from BBSCOMMENT
group by DETAIL_ID, COMMENT_BODY
having count(*) > 1)
order by DETAIL_ID, COMMENT_BODY;
begin
for bbscomment_record in cur_dupl loop
if v_detail_id is null or (bbscomment_record.detail_id != v_detail_id or nvl(bbscomment_record.comment_body, ' ') != nvl(v_comment_body, ' ')) then
--首次进入、换记录了,都重新赋值
v_detail_id := bbscomment_record.detail_id;
v_comment_body := bbscomment_record.comment_body;
else
--其它记录删除
delete from BBSCOMMENT where COMMENT_ID = bbscomment_record.comment_id;
v_counter := v_counter + 1; if mod(v_counter, v_batch_size) = 0 then
--每多少条提交一次
commit;
end if;
end if;
end loop; if v_counter > 0 then
--最后一次提交
commit;
end if; dbms_output.put_line(to_char(v_counter)||'条记录被删除!');
exception
when others then
dbms_output.put_line('sqlerrm-->' ||sqlerrm);
rollback;
end;
Oracle删除重复记录只保留一条数据的几种方法的更多相关文章
- 【转】SQL删除重复记录,只保留其中一条
SQL:删除重复数据,只保留一条用SQL语句,删除掉重复项只保留一条在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢 1.查找表中多余的重复记录,重复记录是根据单个字段(peop ...
- MySQL删除重复记录只保留一条
删除表中重复记录,只保留一条: delete from 表名 where 字段ID in (select * from (select max(字段ID) from 表名 group by 重复的字段 ...
- 从mysql数据库删除重复记录只保留其中一条
这两天做了一个调用第三方接口的小程序,因为是实时更新数据,所以请求接口的频率就很高,这样有时会出现往数据库插入重复的数据,对数据库造成压力也不方便管理,因为要通过原生sql语句,解决数据库的去重问题. ...
- sql server删除重复记录只保留一条
今天遇到一个历史导入数据重复的问题,于是要删除重复的记录,一开始想用子查询的方式找到要删除记录的id删除,后来发现DELETE语句可以直接用外连接,这样更加简单,效率也更高. delete sys_p ...
- mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,
在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记 ...
- 160802、1.06s删除10w条重复记录只保留一条(mysql)及linux删除乱码文件
上次发表过的一遍删除重复记录的文章,其中最优的方案三删除1w条也花了0.07秒而2w条就已经花掉了4秒.今天进行了进一步优化,测试删除10w条只花了1.06秒.速度提升了很多. 建表语句 CREATE ...
- SqlServer_删除重复行只保留一条记录
前提:相同的数据重复往数据库写入,导致存在仅主键Id不同的重复数据,现在需要去除重复数据,仅保留重复数据中Id最大的一条 思路: 1.找出存在重复数据的记录,并取重复数据中最大的Id值 2.删 ...
- MSSQL sql server 2005/2008 row_number()函数应用之–删除表中重复记录,只保留一条不重复数据
转自:http://www.maomao365.com/?p=4942 下文主要讲述:重复数据只获取一条的方法 row_number函数在数据库中的功能是为每一行 按照一定的规则生成一个编号,我们常常 ...
- sql删除表中重复记录只保留一条记录
最终代码 update T_Fee set gzl_dfg_op = 'delete' where MetReadRecordID in ( select MetReadRecordID from T ...
随机推荐
- boost::tie()和boost::variant()解说
#include<iostream> #include<boost/tuple/tuple.hpp> #include<boost/variant.hpp> #in ...
- DevExpress学习03——label控件的背景色问题
今天使用了DevExpress的labelControl,发现拖放上去,其背景色和主窗体的背景一样,非常不谐调,把BackColor设置为透明也不行(Windows中的Label可以). 没有办法,我 ...
- 基于redis分布式锁实现“秒杀”(转载)
转载:http://blog.csdn.net/u010359884/article/details/50310387 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的de ...
- JavaScript原始基础
一.算法 + 数据结构 = 程序 程序=数据结构+算法是由N.Wirth(沃斯)提出来的. 程序是计算机指令的某种组合,控制计算机的工作流程,完成一定的逻辑功能,以实现某种任务: 数据结构指的是数据与 ...
- CheeseZH: Stanford University: Machine Learning Ex1:Linear Regression
(1) How to comput the Cost function in Univirate/Multivariate Linear Regression; (2) How to comput t ...
- shell中如何取括号中的字符
1. 使用grep(结果带括号,不知道有没有办法仅把括号中的内容匹配出来) $a='abc[edg]adfirpqu' $echo $a|grep -o '\[.*\]' #中括号的处理需要转义 [e ...
- ehcache.xml的配置详解和示例
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLoc ...
- gdb 读取elf
在make file中找到ld,然后将其换成 gdb, 如本例中LINKER = /usr/cygnus/xscale-020523/H-sparc-sun-solaris2.5/bin/xscale ...
- Java基础1-反射篇
1.页首请关注 思维导航大纲 2.大牛文章学习: 序号 博主 主要内容 1 sinat_38259539 总结的较全面的反射内容 2 3.自己的理解: 3.1.本文大纲 3.2.正文 1.获 ...
- Linux系统CentOS6.2版本下安装JDK7详细过程
Linux系统CentOS6.2版本下安装JDK7详细过程 分类: Linux 2014-08-25 09:17 1933人阅读 评论(0) 收藏 举报 前言: java 是一种可以撰写 ...