博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle删除重复记录只保留一条数据的几种方法
阅读量:6655 次
发布时间:2019-06-25

本文共 2853 字,大约阅读时间需要 9 分钟。

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 BBSCOMMENTgroup by DETAIL_ID,COMMENT_BODYhaving count(*)>1order by DETAIL_ID, COMMENT_BODY; --1955条

2.2 显示了所有的非冗余的数据

--这一条命令显示了所有的非冗余的数据select min(COMMENT_ID) as COMMENT_ID,DETAIL_ID,COMMENT_BODYfrom BBSCOMMENTgroup 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 awhere    (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;

 

转载地址:http://wcxto.baihongyu.com/

你可能感兴趣的文章
JavaScript函数式编程之记忆(memorize)
查看>>
vimeo
查看>>
网络爬虫的作用和简单分类
查看>>
MySQl 常用操作
查看>>
SD-WAN架构的基本要素:优势和选择
查看>>
52-高级路由:重分发特性:RIP、OSPF
查看>>
LeetCode24-Swap Nodes in Pairs
查看>>
Java架构师学习路线图
查看>>
JPPF与Spring集成实现AOP的完整示例
查看>>
部署DDoS高防需要注意网络安全公司的哪些套路?
查看>>
【前端】前端框架集合与比较(集合贴)
查看>>
MyISAM 表级锁
查看>>
Elasitcsearch High Level Rest Client学习笔记(三)批量api
查看>>
FastReport教程:如何在Angular单页面应用程序中使用Online Designer
查看>>
自从有了企业WiFi管家,老板们都省心了
查看>>
酒店无线覆盖实施的规则
查看>>
高效算法——二分查找
查看>>
Linux几个常用的监控脚本
查看>>
Linux中文件查找技术
查看>>
JVM 垃圾回收机制
查看>>