DB2去重的幾種方法
有兩個意義上的重復記錄,一是完全重復的記錄,也即所有字段均重復的記錄,二是部分關鍵字段重復的記錄,比如Name字段重復,而其他字段不一定重復或都重復可以忽略。
例如下表:table1
用戶辦理套餐的記錄表,可看出,user_id=33333有兩條完全重復的記錄,user_id=11111的tc_name和open_date不一樣
1、對於完全重復的記錄,直接使用distinct 即可
select
distinct user_id,name,tc_name,open_date
from
table1
可得到如下結果:
可以看出,完全重復的記錄已經只剩下唯一的一條,但是部分重復的記錄該方法無效
2、對於完全重復的記錄,還可以使用group by
select
user_id,name,tc_name,open_date
from
table1
group by
user_id,name,tc_name,open_date
結果和上圖一致,即:
該方法也只對完全重復的記錄有效
3、row_number()over() 分等級之后限定 row=1
select
user_id,name,tc_name,open_date
from
(
select
user_id,name,tc_name,open_date
,row_number()over(partition by user_id order by open_date desc) as row
from
table1
)
where row=1
該方法得到的結果如下:
該方法不僅除掉了完全重復的記錄,而且還除掉了不完全重復的記錄,對open_date進行排等級,按照開通日期的倒序排列,且取出第一條記錄,即開通時間最近的記錄
4、max等聚合函數
select
user_id,name,max(tc_name),max(open_date)
from
table1
group by
user_id,name
該方法得出的結果如下,對完全重復記錄和部分重復記錄都有效,注:部分重復的記錄要對所有重復字段使用max或min等才有效
那么在公司的sql語句
select ROW_NUMBER() OVER(ORDER BY max(r.inTime) deSC) AS RN, r.tradeNo,max(r.orderId) as orderId,max(r.orderDate) as orderDate,max(r.merId) as merId,max(r.orderState) as orderState, max(r.amount) as amount,max(r.origAmt) as origAmt,max(r.inTime) as inTime,max(r.modTime) as modTime,max(r.splitState) as splitState, max(r.splitType) as splitType,max(r.splitcategory) as splitcategory,max(p.mainTradeNo) as mainTradeNo, max(p.merId) as merIdSon,max(p.orderId) as orderIdSon from UMPAY.T_PAYORDER_1707 as r left join UMPAY.T_PORDER_SPLIT_SUB_1707 as p on r.tradeNo=p.mainTradeNo where 1 = 1 and r.orderDate BETWEEN '20170720' and '20170721' group by r.tradeNo
對應的要在查詢總體數量的時候也得去重
select count(distinct(r.tradeNo)) from $splitPayorderTableName$ as r left join $splitPorderSUBTableName$ as p on r.tradeNo=p.mainTradeNo where 1 = 1