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;

最新文章

  1. tp框架实现验证码
  2. [Asp.net 5] Localization-简单易用的本地化
  3. stm32 UART串口
  4. HTML 学习笔记 JavaScript (DOM)
  5. IntelliJ IDEA(社区版)学习记录
  6. 进制转换器(十进制转n进制)
  7. zookeeper Keepalived
  8. hibernate uniqueResult方法
  9. mysql performance schema的即时诊断工具-邱伟胜
  10. ASP.NET全局文件与防盗链
  11. javascript类继承系列四(组合继承)
  12. [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
  13. Chosen 基本使用
  14. 转:LoadRunner获取毫秒及字符串替换实现
  15. 1.1.3.托管对象上下文(Core Data 应用程序实践指南)
  16. 分布式进阶(三)Ubuntu 14.04 之JDK安装
  17. Requests卡死问题
  18. 第20月第28天 tensorflow
  19. 有关vue开发的小经验
  20. Codeforces 827E Rusty String - 快速傅里叶变换 - 暴力

热门文章

  1. easyui refresh 刷新两次的解决方法(推荐)
  2. 如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间
  3. C#.NET常见问题(FAQ)-方法参数带ref是什么意思
  4. poj1837--Balance(dp:天平问题)
  5. php之快速入门学习-8(if-else)
  6. 【Maven】IKAnalyzer 在Maven Repository不存在
  7. vue 渲染流程
  8. sp_trace_setfilter sqlserver筛选跟踪或跟踪过滤
  9. Java Method Area
  10. oracle 多字段去重查询