而這樣的流水帳資料表會有兩種需求,第一個想法就是我才不理他,就讓他一直記,一直記,一直一直一直記下去;另一種就是資料表將因為某些原因,去刪除某屬性相同的資料。舉例來說:
上面這張資料表以ID為主鍵,分別記載各區域不同時間的數值,也就是A區域在10月13日為20,到了10月15日為30。有時我們會有一個需求:「我希望以AreaName這個欄位為基礎只留下一份各區域的記載資料」。
那麼,要怎麼達成呢?需求是要留下每一個最新版本的資料,單純的想法就是我們要刪除那些舊的,而舊的資料可能有很多筆,我們或許無法一一列出這些舊有資料,所以應當先篩出MAX(ID)的資料,再反向取得其他舊資料,最後刪掉他們!
所以組SQL語法的順序應該是:
1. 建立依照AreaName欄位選取最大ID的列表的子查詢。(請參考舊文章)
2. 利用上述子查詢以反向選取的方式取得"AreaName有重複的舊資料"(利用NOT IN)。
3. 刪掉第二步驟所列出的子查詢項目。
執行結果:
當然,這種流水帳的資料表可能不會只留下最新資料,我們也許會去刪除5年以前的舊資料,那麼可能會問"如果刪除5年以前的舊資料就直接下刪除2005年以前資料的SQL語法就好了呀?",原因是如果你有1000個區域,而這五年以來只有50個區域更新過,那如果直接刪除2005以前的資料,將會造成有另外50筆的唯一資料一併刪除,造成......不知道會怎麼樣的事情發生。XD
所以我們再增加兩筆A區域的資料,一個為2007年,一個為2004年的資料,來進行上述的刪除動作:
也就是多增加一個時間的篩選,讓他篩出既是舊的而且又在2005年1月1日以前的資料,然後刪掉。
最後還是方便複製,貼上語法:
delete dbo.Table1 where ID in
(Select ID from dbo.Table1 where ID Not IN
(Select MAX(ID) as ID from dbo.Table1 group by AreaName)
AND dbo.Table1.Date <='2005/1/1')
第1句:刪除ID有被第2、3句子查詢所查出的資料。
第2句:列出不被第3句子查詢所查出的項目。
第3句:列出以AreaName群組的最大ID值。
第4句:額外的判斷語句。
沒有留言:
張貼留言