[SQL]如何利用not EXISTS,Partition,ROW_NUMBER找出不存在的資料並重新新增到資料表中

光看標題一定是覺得Jason瘋了! 什麼跟什麼嘛! 我必須先說明一下我原本的需求,近期因為公司透過SBIV的補助計劃,和指導教授一起將一個產品給開發出來,主要是以web的方式來設定及操作社交工程演練,而在這種演練模式之下,會將受檢測者分為是開啟電子郵件,還是點擊了裡面的連結,必須依照理狀況記錄到資料庫中,在演練結束時必須將該結果擷錄成為報告交付,因此在這個過程我們發現了一個狀況,有一些受測者,因為有設定了某種層度的電子郵件防護,因此在開啟郵件時沒有記錄,但是卻產生了點擊郵件的記錄...

光看標題一定是覺得Jason瘋了! 什麼跟什麼嘛! 我必須先說明一下我原本的需求,近期因為公司透過SBIV的補助計劃,和指導教授一起將一個產品給開發出來,主要是以web的方式來設定及操作社交工程演練,而在這種演練模式之下,會將受檢測者分為是開啟電子郵件,還是點擊了裡面的連結,必須依照理狀況記錄到資料庫中,在演練結束時必須將該結果擷錄成為報告交付,因此在這個過程我們發現了一個狀況,有一些受測者,因為有設定了某種層度的電子郵件防護,因此在開啟郵件時沒有記錄,但是卻產生了點擊郵件的記錄。

也許是我們的範本設計的太好了,讓不少的社交工程演練受測者都有點擊連結,但是卻都沒有收到該使用者的開信記錄,在交付報告時,負責承辦人提出這個疑問,為什麼有某個單位的點擊率這麼高,但讀取率卻這麼低,經過解釋後,承辦人接受了我們的說明,確實在開信時是可以透過讀信的功能去把偵測開信的動作給阻擋掉的,那麼,這個點擊的時間記錄該怎麼處理呢?該受測者確實也讀了信,確實也點了連結,因為每一個受測者都有一個獨一無二的編碼,怎麼可能沒有讀信就可以直接開啟連結,且這個獨一無二的編碼及web service的串連,不可能就這麼剛好被猜中,查詢了IIS上的存取記錄和資料庫的記錄相同。

這個時侯,承辦人提出了一個需求,任何有點擊過連結的使用者,應該要忠實的記錄下來,但是開信的時間和動作也應該要被追溯回來,所以直接以開啟連結的時間,做為讀信的時間才是!

這下好了! 資料庫中是透過欄位來記錄的:識別碼、動作(開連結、讀信)、動作時間,所以我們必須先把有開開連動作,沒有讀信時間的記錄找出來,嗯!應該不難,可以先透過SQL裡面的記錄拆成開連結和讀信,接下來透過not Exists來達成! 所以我先把資料庫中有開信的記錄透過select into給列到另一張表去(這一段我就不說明了!)。

接下來就來使用not exists來把有開連結(Action=C),沒有讀信(Action=R)的資料找出來!

SELECT *
FROM noRead
WHERE not EXISTS
    (SELECT Identifier,ActionTime
     from EvaluateResult
     where noRead.Identifier=EvaluateResult.Identifier
     and action='R')

結果就是下面這樣,共有127筆

image

 

接下來我就將上面的方法存成一個VIEW,免得未來又發生這樣的狀況,當然,後來也提出來給我們公司負責開發的夥伴們,請他們幫我查一下,收到一筆來自開啟連結動作的記錄時,先查一下資料庫是否有讀信記錄,沒有就自動加上去!

接下來我們再將這個view重新的拿來利用,加上row_number及partition,以partition將識別的Identifier為依據再把觸發時間做大到小的排序,再將row_number幫每一筆識別資料有多筆的讀信記錄加上流水號,結果就像下面這樣

	Select *,ROW_NUMBER() Over (Partition By identifier Order By actiontime Desc) As Sort From  dbo.notReadRecord

image

 

透過上面的方法,我們已經取出了每一個開連結記錄的時間及排序,接下來,只要再把sort是1的列出來,重新把識別讀信動作的Action=R重新插回記錄中

	insert into EvaluateResult(Identifier,Action,ActionTime)
	select Identifier,N'R',Actiontime from(
	    Select *,ROW_NUMBER() Over (Partition By identifier Order By actiontime Desc) As Sort From  dbo.notReadRecord
	) tmp
	where tmp.Sort=1
        

先看一下select 出來的對不對,只剩下73筆記錄,看起來,我們的範本很成功,近一半以上的數字是重覆的

image

 

如此一來就完成了從資料集中找出不存在的記錄,再將所需要的資料重新的插回到資料庫中,如果沒有程式設計的夥伴們,我也只能土法煉鋼的把T-Script或透過觸發程序來做這個檢查,以上是處理客戶需求的過程,現在明白我的明白了嗎?當然一定有比這個更快的方法,但資料不多的狀況下,先應急應急吧!


Anything keeps Availability.
Anywhere keeps Integrity.
Anytime keeps Confidentiality.
keep A.I.C. = Information Security