排名函數是SQL SERVER2005新增的函數。排名函數總共有四種,分別是:row_number、rank、 dense_rank 、ntile。
row_number:順序生成序號。
rank:相同的序值序號相同,但序號會跳號。
dense_rank :相同的序值序號相同,序號順序遞增。
ntile:裝桶,把記錄分成指的桶數,編序號。
下面分別介紹一下這四個排名函數的功能及用法。在介紹之前假設有一個t_table表,表結構與表中的數據如圖1所示:
圖1
其中field1字段的類型是int,field2字段的類型是varchar。
一、row_number
row_number函數的用途是非常廣泛,這個函數的功能是為查詢出來的每一行記錄生成一個序號。row_number函數的用法如下面的SQL語句所示:
select row_number() over(order by field1) as row_number,* from t_table
上面的SQL語句的查詢結果如圖2所示。
圖2
其中row_number列是由row_number函數生成的序號列。在使用row_number函數是要使用over子句選擇對某一列進行排序,然后才能生成序號。
實際上,row_number函數生成序號的基本原理是先使用over子句中的排序語句對記錄進行排序,然后按着這個順序生成序號。over子句中的order by子句與SQL語句中的order by子句沒有任何關系,這兩處的order by 可以完全不同,如下面的SQL語句所示:
select row_number() over(order by field2 desc) as row_number,* from t_table order by field1 desc
上面的SQL語句的查詢結果如圖3所示。
圖3
我們可以使用row_number函數來實現查詢表中指定范圍的記錄,一般將其應用到Web應用程序的分頁功能上。下面的SQL語句可以查詢t_table表中第2條和第3條記錄:
-
with t_rowtable
-
as
-
(
-
select row_number() over(order by field1) as row_number,* from t_table
-
)
-
select * from t_rowtable where row_number>1 and row_number < 4 order by field1
上面的SQL語句的查詢結果如圖4所示。
圖4
另外要注意的是,如果將row_number函數用於分頁處理,over子句中的order by 與排序記錄的order by 應相同,否則生成的序號可能不是有續的。
二、rank
rank函數考慮到了over子句中排序字段值相同的情況,為了更容易說明問題,在t_table表中再加一條記錄,如圖5所示。
圖5
select rank() over(order by field1),* from t_table order by field1
上面的SQL語句的查詢結果如圖6所示。
圖6
三、dense_rank
dense_rank函數的功能與rank函數類似,只是在生成序號時是連續的,而rank函數生成的序號有可能不連續。如上面的例子中如果使用dense_rank函數,第4條記錄的序號應該是2,而不是4。如下面的SQL語句所示:
select dense_rank() over(order by field1),* from t_table order by field1
面的SQL語句的查詢結果如圖7所示。
圖7
四、ntile
ntile函數可以對序號進行分組處理。這就相當於將查詢出來的記錄集放到指定長度的數組中,每一個數組元素存放一定數量的記錄。ntile函數為每條記錄生成的序號就是這條記錄所有的數組元素的索引(從1開始)。也可以將每一個分配記錄的數組元素稱為“桶”。ntile函數有一個參數,用來指定桶數。下面的SQL語句使用ntile函數對t_table表進行了裝桶處理:
select ntile(4) over(order by field1) as bucket,* from t_table
上面的SQL語句的查詢結果如圖8所示。
圖8
由於t_table表的記錄總數是6,而上面的SQL語句中的ntile函數指定了桶數為4。
https://blog.csdn.net/qq_30725967/article/details/88572541