[MSSQL]SQL疑難雜症實戰記錄-巧妙利用PARTITION分組排名遞增特性解決合併連續相同數據行

問題提出

先造一些測試數據以說明題目:html

DECLARE @TestData TABLE(ID INT,Col1 VARCHAR(20),Col2 VARCHAR(20))
INSERT INTO @TestData(ID,Col1,Col2)
SELECT 1,'New','Approved' UNION ALL
SELECT 2,'Approved','Commited' UNION ALL
SELECT 3,'Commited','In Progress' UNION ALL
SELECT 4,'New','Approved' UNION ALL
SELECT 5,'New','Approved' UNION ALL
SELECT 6,'New','Approved' UNION ALL
SELECT 7,'Approved','Removed'
SELECT * FROM @TestData函數

image

image

 

數聽說明,ID列連續自增,列1和列2都是TFS中PBI的狀態記錄,就是從什麼變動到什麼,如新建到批准,批准到提交神馬的測試

如今要求連續且相同的狀態變動記錄合併,不連續或者不一樣的狀態變動保留,例如:3d

以上圖爲例,ID爲1,4,5,6的記錄都是從NewApproved狀態,可是記錄1與記錄四、五、6不相鄰,或者說不連續,那麼就要分紅兩組,htm

記錄1一組,記錄四、五、6一組,其它記錄由於狀態變動不相同因此所有保留,最後的查詢結果應該長成下圖這個樣子:blog

image

繼續以前你能夠先本身試下,這可能會帶來新的解題思路,get

 

解題思路

該問題的關鍵在於GROUP BY會把記錄一、四、五、6合併在一塊兒,而這不符合要求,僅須要合併四、五、6,源表裏沒有這樣一個字段能夠將記錄1與記錄四、五、6區分開來,這是解題的關鍵it

這裏能夠利用RANK函數配合使用PARTITION關鍵字,首先把1456分到一組去,同時產生一個組內排名的新字段R,這個排名R很關鍵,後邊會用到,見下圖:im

image

RANK函數不瞭解的點這裏d3

RANK函數以Col1 + Col2爲分組條件,這樣分紅了四組,分別是New-Approved、Approved-Commited、Commited-In Progress、Approved-Removed

在New-Approved組內,記錄一、四、五、6分別排名一、二、三、4;其它組內僅一條記錄,在其組內排名均爲1

如今製造了一個R字段,R字段標識了每條記錄在其組內的排名,排名自1開始遞增,

源表內ID自增,組內排名R遞增,這就是解題的關鍵,

當連續相同的記錄出現時,其ID與其排名R在同時遞增,則其差值是相同的,拿到這個差值就能夠很容易解決題目了,看下圖:

image

記錄四、五、6相同且連續出現,其ID與其排名在同時增加,其差值則保持不變,這裏使用Col1 + Col2 + Gap做爲分組條件便可將記錄四、五、6合併,再取個最小ID出來,問題解決,完整腳本以下:

image

但是若是ID不連續時怎麼辦呢?這個不難,參考[MSSQL]ROW_NUMBER函數

相關文章
相關標籤/搜索