Oracle去重而儲存時間最新的資料
本篇文章僅僅是我工作上的一個随筆記錄,寫的不是很詳細,如果不了解我所做的工作的業務内容,可能會看的一頭霧水。大家可以僅做為一種參考思路!
場景描述:
單據表 fdcpm_pay_apply 中的财務處理狀态的值一直是從财務中間表 mid_fina_x 中擷取的
現在我們在 fdcpm_pay_apply 中添加一個 ifinastatus 的字段用來直接存儲财務處理狀态的值,并且以後就按照這種方式存儲,是以需要把财務中間表中已有的财務處理狀态給刷到對應單據的 ifinastatus字段中。
檢視表中重複的資料有哪些(去掉重複,隻顯示單據編碼vbillcode)
SELECT vbillcode FROM mid_fina WHERE NVL(dr,0)=0 GROUP BY vbillcode HAVING COUNT(*)>1;
通過上步查詢出來的vbillcode,可以查詢出所有重複的資料
SELECT * FROM mid_fina WHERE NVL(dr,0)=0 AND vbillcode IN(
SELECT vbillcode FROM mid_fina WHERE NVL(dr,0)=0 GROUP BY vbillcode HAVING COUNT(*)>1
);
那麼我們為了以防萬一,複制一張一模一樣的表來進行下一步的處理
CREATE TABLE mid_fina_x AS (SELECT * FROM mid_fina WHERE NVL(dr,0)=0);
查詢資料中vbillcode相等,但是修改時間比較早的資料
SELECT * FROM mid_fina_x mf WHERE mf.ts < (
SELECT MAX(mx.ts) FROM mid_fina_x mx WHERE mf.vbillcode=mx.vbillcode AND NVL(mx.dr,0)=0
) AND NVL(mf.dr,0)=0;
删除這些重複資料中的舊資料,隻保留最新的那一條
DELETE FROM mid_fina_x mf WHERE mf.ts < (
SELECT MAX(mx.ts) FROM mid_fina_x mx WHERE mf.vbillcode=mx.vbillcode AND NVL(mx.dr,0)=0
) AND NVL(mf.dr,0)=0;
需要注意的是,按上述方法删除重複資料,隻會删除時間比最新時間早的資料,如果有兩條資料,他們的vbillcode和ts修改時間都是一樣的,那麼這兩條資料都不會被删除,是以我們需要再次過來一次重複資料
前一次過濾是通過ts修改時間,那麼這次我們可以選擇其他有序的字段進行過濾,畢竟,如果幾條資料的vbillcode和ts修改時間都相同的情況下,我們隻需要取其中的某一條(不管那一條)資料的paystatus财務處理狀态的值
DELETE FROM mid_fina_x mf WHERE mf.pk_pa_payrefinfo < (
SELECT MAX(mx.pk_pa_payrefinfo) FROM mid_fina_x mx WHERE mf.vbillcode=mx.vbillcode AND NVL(mx.dr,0)=0
) AND NVL(mf.dr,0)=0;
那麼我們現在得到的 mid_fina_x 表就是沒有重複資料的資料表了。
