SQL_过滤无主键千万级表中多字段中分布重复项

本文介绍了一种在Oracle环境下使用PL/SQL处理大量重复数据的方法。通过添加唯一ID、定位重复记录、并最终删除非唯一记录的方式,确保了每个SN号只对应一条最新登记时间的记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL爬坑系列三最近一直在弄WEB开发,难得分配到点数据分析任务继续SQL探索。。。本次SQL为Oracle下PL/SQL

 

借鉴:

http://www.ituring.com.cn/book/tupubarticle/19042 用于删除重复行的高效 SQL

http://bbs.youkuaiyun.com/topics/80166135 多个字段分布重复项如何过滤

 

业务场景:

在无主键、行数千万以上的单表中,进行数据过滤,保障表中每个SN号唯一,且只对应一条最新登记时间的记录。表中存在对一个SN号的多次登记记录;同样内容的SN号与LOGTIME字段重复记录;一个SN号出现多次等情况。现简单罗列如下:

 

SN

LOGTIME

2015210539

20161021123234

2013210541

20130612013211

2013210541

20130612013211

2017210512

20170722224031

2017210512

20170722224029

2017210512

20170722224057

2016210512

20170722224048

2016210512

20170819194255

2016210512

20170819194255

 

方法思路:

本业务的难点在于,大数据量下过滤多字段重复记录并定位它们。鉴于数据量大,最好只针对重复数据进行处理,不要让整张千万级表都参与计算。

 

具体步骤:(四、五、六为重点)

 

第一步:为表增加主键ID字段NUMBER型,标识唯一,为后续铺垫;

 

第二步:在千万级表中,定位重复的记录,观察重复记录的情况;

SELECT *

FROM TABLE

WHERE SN IN

(

SELECT SN FROM TABLE

GROUP BY SN HAVING "COUNT"(1)>1

)

 

第三步:为重复记录的ID赋值唯一数据编号;

UPDATE TABLE

SET ID = ROWNUM

WHERE SN IN

(

SELECT SN FROM TABLE

GROUP BY SN HAVING "COUNT"(1)>1

)

  

第四步:获取TABLE上,唯一的SN号与最新登记时间一一对应的数据;

SELECT SN,"MAX"("TO_NUMBER"( LOGTIME)) AS LOGTIME

FROM TABLE

GROUP BY SN

 

第五步:获取TABLE表过滤掉SN与LOGTIME内容相同的重复数据和后的数据;

SELECT "MAX"(ID) AS ID FROM TABLE GROUP BY SN,LOGTIME; 



第六步
:因为第四步,GROUP BY,带不了ID,所以此处利用拼接字符串,获取过滤重复后,对应的唯一ID对应最新时间记录。结合四、五两步基础上,在第五步过滤SN、LOGTIME内容都重复的记录后,获取第四步SN与LOGTIME完全一致的记录; 

SELECT SN,"MAX"("TO_NUMBER"( LOGTIME)) AS LOGTIME

FROM TABLE

WHERE SN||','|| LOGTIME

IN

(

SELECT A.SN||','||A. LOGTIME

FROM

(

SELECT SN,"MAX"("TO_NUMBER"( LOGTIME)) AS LOGTIME

FROM TABLE

GROUP BY SN

) A

)

AND ID IS NOT NULL

GROUPBY SN

第七步:删除不是唯一ID对应最新时间的记录

DELETE FROM TABLE

WHERE ID NOT IN

(

SELECT SN,"MAX"("TO_NUMBER"( LOGTIME)) AS LOGTIME

FROM TABLE

WHERE SN||','|| LOGTIME

IN

(

    SELECT A.SN||','||A. LOGTIME

    FROM

    (

    SELECT SN,"MAX"("TO_NUMBER"( LOGTIME)) AS LOGTIME

    FROM TABLE

    GROUP BY SN

    )A

)

AND ID IS NOT NULL

GROUP BY SN

)

AND ID IS NOT NULL


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值