摘要:應用SqlServer2005開發也已經有一段時間了,但是很多時候都是把SqlServer2005當做SqlServer2000來用,因此很多SqlServer2005的新特性我都沒有用到,有一個原因就是要兼容SqlServer2000的用戶。新特性出來的當然就要用於實際當中,要想知道SQLServer2005的新特性可以參看微軟網站的What's New in SQL Server 2005? ,特性有很多本篇文章主要介紹的是在數據庫中返回特定順序的記錄集。
數據庫模型:
在我們深入Sql排序語句時,我們先來看看數據庫模型,也就是我們要建立一個數據庫並通過這個數據庫來進行我們的講解。我們建立一個產品數據庫,首先我們要建立一個產品表Products,包含ProductID(主鍵),Name,Price三個字段.這是一個很簡單的數據庫,下面我們就運用這個數據庫來講解以下排序。
SQLServer2005提供我們四個排序函數:ROW_NUMBER, RANK, DENSE_RANK和NTILE,(據我了解)這四個函數在SqlServer2000中是沒有的,在不同的場合我們可以選用這四個函數,他們各有各的特點,下面我們就逐個來看一下他們各個的特性。
ROW_NUMBER():
這個函數是通過對特定列來排序的,也就是說我們要指定按哪個列來排序。我們要知道他的特性當然首先我們要知道他的語法:
ROW_NUMBER()OVER([partition]order-by-clause)
先看例子,例如我們要從產品Products中的每一個產品按價格的高低排列出來,並得到每一個產品所在的序列號,代碼如下:
SELECT[ProductID],[Name],[Price],
ROW_NUMBER()OVER(ORDERBY[Price]DESC)ASRank
FROMProducts
則在返回的結果中將會出現Rank列,此列將從1開始逐行加1(1,2,3,…),這樣我們就可以很靈活的應用這個功能來分頁提取記錄。下面我們來看看怎樣來實現快速分頁,假設我們每頁顯示的記錄數位@PageSize,當前頁面為@PageIndex,我們就可以用如下代碼來進行分頁:
SELECTTOP(@PageSize)[ProductID],[Name],[Price]
FROM
(
SELECT[ProductID],[Name],[Price],ROW_NUMBER()OVER(ORDERBY[Price]DESC)ASRank
FROMProducts
)ASP
WHERERankBETWEEN((@PageIndex-1)*@PageSize+1)AND@PageSize*@PageIndex
RANK(), DENSE_RANK():
從上面的例子中我們知道了ROW_NUMBER()函數可以返回按一定列排列的行號。但是在兩個相同記錄中,例如我們的產品甲和乙的價格都為1RMB,在ROW_NUMBER()中將返回甲乙的順序為#1,#2。但是有時候我們需要的是相同的記錄返回相同的行號,如上面所說的將返回的行號為(甲) #1(乙)#1,這樣我們就需要用到這裡所要講述的兩個函數RANK()和DENSE_RANK()函數。用法和ROW_NUMBER的用法一樣:
SELECT[ProductID],[Name],[Price],
RANK()OVER(ORDERBY[Price]DESC)ASRank
FROMProducts
我們可以知道RANK()和DENSE_RANK()都能達到效果,而不同的是,RANK()將跳過相同的記錄數的行號。也就是說雖然行號相同,但是下頁個不同列值的行號將是這幾個行號之和加上他們的行號。如上述的甲乙為#1,用RANK()者返回丙的結果為#3,而DENSE_RANK()返回丙的結果為#2。
NTILE():
當我們需要將給過分組排序時就要用到NTILE(),例如我們將所有的產品按照價格的高低從大到小分為5組,我們就可以用如下代碼:
SELECTProductID,Name,Price,NTILE(5)OVER(ORDERBYPriceDESC)ASP
FROMProduts
這樣將所有記錄分成5份,按價格高低有1到5分開。
總結:
本文講述的四個函數ROW_NUMBER, RANK, DENSE_RANK和NTILE都能夠排序返回記錄集,我想用的最多的就是應用ROW_NUMBER進行快速分頁。其實他們四個各有各的特點,在我們平時的應用中靈活應用他們能夠給我們帶來很多的便利,很多的快樂!同時也希望這篇文章能夠給大家帶來點幫助,帶來一點快樂!