背景:一般在增量导入数据后,表中会出现冗余的数据,因此对于表的去重操作主要分为两种:去重查询以及删除重复数据
1. 去重查询
1.1 distinct 关键字
selectdistinct<col1, col2, ...>from<table1>;
2. 删除重复数据
删除重复数据主要分为两种:部分去重和完全去重
2.1 部分去重
部分去重分为两个步骤:
2.1.1 找出重复数据
select<col1, col2, ...,count()>from<table1>groupby<col1, col2, ...>havingcount()>1;
2.1.2 删除临时数据
deletefrom<table1 a>where<col1, col2>in(select col1, col2, ...,count()from<table1>groupby col1, col2, ... havingcount()>1);
进阶:如果当数据量非常大的时候,上面的删除执行效率会非常低,甚至有可能导致数据库卡死,因此可以用临时表来减轻数据库io的压力
--创建临时表保存重复数据createtable tmp as(select<col1, col2, ...,count()>from<table1>groupby<col1, col2, ...>havingcount(*)>1);--删除原表中的重复数据deletefrom<table1 a>where(col1, col2, ...)in(select col1, col2, ... from tmp);--删除临时表droptable tmp;
2.2 完全去重
当数据体量小的时候,可以考虑完全去重。
--创建临时表保存去重后的数据createtable tmp as(selectdistinct*from<table1>);--清空原表数据truncate table<table1>;--将临时表的数据插入到原表中insertinto<table1>(select*from tmp);--删除临时表droptable tmp;
3. 进阶用法
背景:如果数据10分钟导入一次,一小时导入一次,甚至一天导入一次,而且每次导入的数据都得进行去重,那么上述sql语句就会重复执行,我们如何实现其自动化?
答案是触发器,下面我写得一个应用触发器的事例,数据库用的是Kingbase(人大金仓V8),当然如果熟悉触发器的朋友也可以插入前检验,不过博主不擅长写referencing old old new new的前置触发,所以不在此举例。
CREATEOR REPLACE TRIGGER "clear_replica"--触发条件:当插入数据至LsvoFplnCmdcCoreItems表时会触发动作,也可以加其他触发条件比如 UPDATE, DELETE, 需用OR连接AFTER INSERTON LsvoFplnCmdcCoreItems FOR EACH ROW ASBEGIN--创建临时表保存重复数据CREATETABLE tmp AS(SELECT CompanyCode, BusinessTypeCode, SubBusinessTypeCode, SupplierCode, CurrencyCode, IsInit, ExecAmt, PayDate, version FROM LsvoFplnCmdcCoreItems GROUPBY CompanyCode, BusinessTypeCode, SubBusinessTypeCode, SupplierCode, CurrencyCode, IsInit, ExecAmt, PayDate, version HAVINGcount(*)>1);--删除原表中的重复数据deletefrom LsvoFplnCmdcCoreItems where(CompanyCode, BusinessTypeCode, SubBusinessTypeCode, SupplierCode, CurrencyCode, IsInit, ExecAmt, PayDate, version)in(select CompanyCode, BusinessTypeCode, SubBusinessTypeCode, SupplierCode, CurrencyCode, IsInit, ExecAmt, PayDate, version from tmp);--删除临时表droptable tmp;END;