1. 程式人生 > >查詢重複資料(某個欄位允許指定範圍內偏移)

查詢重複資料(某個欄位允許指定範圍內偏移)

前一段時間遇到一個問題,要求在pg資料庫環境下編寫一個sql,實現相同記錄在不同商家的查詢規則,因為相對於商家來說有些在a商店購入的記錄會在b商店顯示為賣出,而且交易的時間有時也不會完全一樣,針對這樣的情況,我嘗試了許多次但都不能使用一個sql來實現,遂使用了臨時表的方式來進行多次查詢操作:

介紹下表和欄位:原始表tb,欄位pa1,pa2與pb1,pb2相對應不同方向的相關欄位,pc為時間欄位,pd為方向;

首先第一步,把所有現有的指定欄位相同交易方向的重複資料剔除,不重複的資料放在臨時表中備用:

drop table if exists tmp_tb1;

select * into tb from(select * ,row_number() over(partition by pa1,pa2,pb1,pb2,pc,pd order by pc)t from tb )tp where tp.t=1;

select ...into... from用來將查詢的資料匯入一個不存在的表;

第二步,將交易資料的改成交易方向相同的資料,交易方向保持不變:

drop table if exists tmp_tb2;

select *,row_number() over(partition by pa1,pa2,pb1,pb2,pc ,pd order by pc) t into tmp_tb2 from(select id,pb1 pa1,pb2 pa2,pa1 pb1,pa2 pb2,pc from tmp_tb1 where pd like '%進%'

union all 

select id,pa1,pa2,pb1,pb2,pc,pd from tmp_tb1 where pd like '%出%')tp;


第三步,獲取指定偏移時間內的資料:

drop if exists tmp_tb3;

select id,pa1,pa2,pb1,pb2,pc,pd,id1,id2,bmini,cmini into tmp_tb3 from(

select a.*,b.id id1,c.id id2,abs(extract(epoch from(a.pc-b.pc))) bmini,abs(extract(epoch from(a.pc-c.pc))) cmini from

tmp_tb2 a 

left join tmp_tb2 b on a.pd<>b.pd and a.pa1=b.pa1 and a.pa2=b.pa2 and a.pb1=b.pb1 and a.pb2=b.pb2 and a.t=b.t-1 

and abs(extract(epoch from(a.pc-b.pc))) between 0 and(60*$filter$)

left join tmp_tb2 c 

on a.pd<>b.pd and a.pa1=c.pa1 and a.pa2=c.pa2 and a.pb1=c.pb1 and a.pb2=c.pb2 and a.t=c.t+1 

and abs(extract(epoch from(a.pc-c.pc))) between 0 and(60*$filter$)

)tp where bmini is not null or cmini is not null;

上述sql中$filter$為指定偏移分鐘的佔位符,abs(extract(epoch from(a.pc-c.pc)))最內層epoch from配合extract可計算出指定時間的秒數,可能為負,所以取絕對值;


最後,查詢最終結果:

select * from tb where id in(select id from tmp_tb3)


如果想刪除這部分重複資料:

delete from tb where id in(select id from tmp_tb3 where id2  in(select id from tmp_tb3 where id1 is not null))