Greenplum/PostgreSQL中數據表數據去重的幾種方法


GP主要用於數據倉庫領域,在GP數據庫中,如果由於ETL重復跑數導致數據重復的話,就需要進行去重復操作。

一種方法是把某一時間段的數據全部刪掉,然后重新跑數據,這樣其實工作量也比較大,需要補數據,重跑ETL。

另一種方法就是把重復的數據刪掉就行,本文就是針對Greenplum分布式數據庫如何進行去重復刪除操作。

對於在PostgreSQL中,唯一確定一行的位置的是用ctid,可以用這個ctid作為一行的唯一標識;在Oracle中,數據表中的一行的唯一標識可以使用ROWID進行標識,這作為這一行的物理地址信息。而在GP中,要唯一的標識出一行表數據,需要使用gp_segment_id加上ctid進行標識。 gp_segment_id代表的是GP的segment的節點標識,每個子庫的標識是唯一的。

因此刪除重復數據的語句可以這么寫:

delete from public.ods_m_monitor_hour where gp_segment_id::varchar(100)||ctid::varchar(100) in
(select t.ctid from
(select gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour  ) t
where t.rows_num >=2);

或:

delete from public.ods_m_monitor_hour where (gp_segment_id,ctid) in
(select t.gp_segment_id,t.ctid from
(select gp_segment_id,ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour ) t
where t.rows_num >=2);

 

這種語句適合所有的GP表,特別對那種沒有唯一主鍵的數據倉庫的表進行去重很有用。

用第一種方法分析下步驟:

先分析下,第一步:

select gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour 

查出來public.ods_m_monitor_hour 表中字段

gp_segment_id::varchar(100)||ctid::varchar(100) as ctid,mn_code,pollute_code,monitor_time

其中mn_code,pollute_code,monitor_time這幾個字段是這個表中能夠保證唯一性的字段,也就是這幾個字段的值的任一某個組合在這張表只能出現一次,只要出現2次以上,就說明

數據重復了。

然后通過row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num對這幾個字段進行分組排序

通過在外層對這個排序字段rows_num進行條件判斷 :where t.rows_num >=2,就能過濾出重復的表數據。

然后再通過外部條件進行篩選,獲取出這部分重復數據的行數據唯一標識:

delete from public.ods_m_monitor_hour  where gp_segment_id::varchar(100)||ctid::varchar(100) in 
(select t.ctid from ……)就可以去重重復。

 

另外,如果表中有唯一標識行的pkid,也就是說有主鍵ID的話,那直接用PKID作為去重字段:

delete from public.ods_m_monitor_hour  where pkid in
(select pkid from
(select pkid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour  ) t
where t.rows_num >=2);

 

postgresql中去重:

delete from public.ods_m_monitor_hour  where ctid in
(select ctid from
(select ctid,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour ) t
where t.rows_num >=2);

 另外:

oracle中去重:

delete from public.ods_m_monitor_hour  where ROWID in
(select ROWID from
(select ROWID,mn_code,pollute_code,monitor_time,
row_number() over (partition by mn_code,pollute_code,monitor_time) rows_num
from public.ods_m_monitor_hour  ) t
where t.rows_num >=2);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM