20120320

T-SQL - 使用MERGE指令組合不同資料表之資料

說明

SQL SERVER 2008中,新增了一項指令「MERGE」。此指令之前僅見於ORACLE中,這次微軟將它加入到SQL SERVER 2008,可謂是從善如流。

 

那這個「MERGE」到底有什麼用呢?

 

常常處理資料庫的人就會知道,資料庫最麻煩的地方就是在於「統合」資料。因為資料唯有在和其他資料比對之後,才會出現有意義的資料;所以資料間的統合,就是資料庫最大的賣點。

 

但是這對於我們程式設計師來說,卻是一項惡夢。

 

在沒有「MERGE」這個指令之前,我們若是要統整二張不同的資料表(或是同一張資料表間的資料進行再統合),都需要下不少的T-SQL指令,而且還不一定能夠達成我們想要的結果。

 

甚至有時乾脆利用C#或其他程式語言,來代替T-SQL達到我們想要的結果。其原因就在於目前的T-SQL對於逐筆資料的操作,並不是那麼如其他程式語言那樣地直覺。

 

但是現在有了「MERGE」,我們就可以補上這一塊缺口。

 

例如說,我們有A, B二個資料表,其中A的KEY和B的KEY相同,但是其他欄位不同,所以我們想要將這二個表合成一張新的C資料表。這在以前的T-SQL不知道要花多少工,通常我都是直接利用C#來完成這項工作(因為我不太會用CURSOR)。不過現在我們就可以利用「MERGE」這項指令來完成這項工作。

 

下面看看例子。

 

 

解決方法

語法:

  1: DECLARE @mk int
  2: DECLARE @mBirth datetime
  3: DECLARE @mSex int
  4: DECLARE @MonthAgeMax int
  5: 
  6: SET @mk = 6
  7: SET @mBirth = '2011/10/22'
  8: SET @mSex = 0
  9: SET @MonthAgeMax = 12
 10: 
 11: -- 宣告暫存資料表,用以儲存GROUP BY資料
 12: DECLARE @TEMP_1 TABLE
 13: (
 14:   MonthAge int,
 15:   Height float
 16: )
 17: 
 18: -- 塞入資料
 19: INSERT INTO @TEMP_1
 20:   SELECT
 21:   (DATEDIFF(MM, @mBirth, blTimeRecord)-1) AS MonthAge,
 22:   MAX(blHeight) AS Height
 23: FROM Log
 24: WHERE
 25:   (mk = @mk)
 26: GROUP BY (DATEDIFF(MM, @mBirth, blTimeRecord) -1)
 27: 
 28: -- 宣告回傳用Table
 29: DECLARE @TEMP_2 TABLE
 30: (
 31:   MonthAge int,
 32:   Height float NULL,
 33:   P1 float,
 34:   P3 float,
 35:   P5 float,
 36:   P15 float,
 37:   P25 float,
 38:   P50 float,
 39:   P75 float,
 40:   P85 float,
 41:   P95 float,
 42:   P97 float,
 43:   P99 float
 44: )
 45: 
 46: -- 塞入指定期間之資料
 47: INSERT INTO @TEMP_2
 48: SELECT
 49:   MonthAge, NULL, w.P1, w.P3,w.P5,
 50:   w.P15, w.P25, w.P50, w.P75,
 51:   w.P85, w.P95, w.P97, w.P99
 52: FROM WTO_Height AS w
 53: WHERE 
 54:   (w.Sex = @mSex) AND
 55:   (w.MonthAge <= @MonthAgeMax)
 56: 
 57: -- 塞入資料
 58: MERGE INTO @TEMP_2 AS C2
 59: USING @TEMP_1 AS C1
 60: ON (C1.MonthAge = C2.MonthAge)
 61: WHEN MATCHED THEN
 62:   UPDATE SET C2.Height = C1.Height
 63: WHEN NOT MATCHED BY TARGET THEN
 64:   INSERT (MonthAge, Height)
 65:   VALUES (C1.MonthAge, C1.Height);
 66: 
 67: -- 回傳資料
 68: SELECT * FROM @TEMP_2


說明:

這是一段Stored Procedure,其中,我們先將資料匯入到@TEMP_1, @TEMP_2二個暫存資料表,之後再利用MERGE指令,將@TEMP_1的資料匯總到@TEMP_2中。

 

 

參考網址

MERGE (Transact-SQL)

使用 MERGE 插入、更新,和刪除資料

沒有留言: