最近項目中須要在SQL SERVER中進行分頁,須要編寫分頁查詢語句。以前也寫過一些關於分頁查詢的語句,可是性能不敢恭維。因而在業務時間,在微軟社區Bing了一篇老外寫的關於SQL SERVER分頁的文章。看過以後,感受本身以前寫的語句,過低端,太不科學了。 文章中講了兩種分頁方法,其中一種只適用於SQL SERVER2012以上版本。sql
ROW_NUMBER()函數分頁express
先介紹一下ROW_NUMBER()函數,這個函數的主要做用,從它的命名中就可看出來。ROW,每列,NUMBER數字,它的做用就是爲每行分配一個數字。可是它通常不單獨使用。它的語法是這樣的:函數
PARTITION BY value_expression: 這個參數是經過value_expression,把咱們查詢到結果集給分紅若干區。舉個例子,咱們有一張成績表。咱們要爲女生、男生在各自性別內按成績排名次。這時,咱們就能夠經過PARTITTION BY GENDER(性別字段) 將全班人員分爲兩個區,女生區、男生區。男生在男生區排名次,女生在女生區排名次。性能
order_by_clause:這個是就是order by 語句,將數據集按某個字段進行排序。學習
須要注意的是,PARTITION BY value_expression不是必要參數,可是order_by_clause是必要參數。要使用ROW_NUMBER()必需要有order by 語句。下面給出幾個ROW_NUMBER() 實際使用場景:fetch
1.spa
這個語句把表中TerritoryName不爲空、SalesYID不爲空的數據按字段SalesYTD降序排序,再經過ROW_NUMBER()函數爲每行分配一個連續的數字,將數字存入新添加的一個名爲Row的字段中。結果以下:3d
2.這種狀況,就是咱們今天要講的分頁方法。(Returning a subset of rows)code
在這個場景中,咱們用到了Comoon table expression(中間表表達式),它的做用與臨時表差很少。就是將查詢到的結果放入一個地方,供再次查詢。對Common Table Expression感興趣的能夠去MSDN上學習。原文地址:http://msdn.microsoft.com/en-us/library/ms175972.aspx.server
咱們使用ROW_NUMBER()函數爲查詢的結果每行數據分配一個數字,將數字放入RowNumber列中(經過AS 生成的新列)。再將數據集放入中間表OrderedOrders中。查詢中間表,這個時候咱們就可使用Where RowNumber BETWEEN A AND B.來讀取從A條到B條的數據了,就能夠達到咱們的分頁需求了.
3.Using ROW_NUMBER() with PARTITION
在這個場景中,咱們用到了PARTITION參數。咱們按區域(territoryName)將查詢結果進行分區,再在分過區的數據集中以SalesYTD降序,再爲降序後的每行數據分配數字。最後以TerritoryName字段升序。結果以下圖:
關於ROW_NUMBER()的原文地址:http://msdn.microsoft.com/en-us/library/ms186734.aspx.
這種分頁方法的主要思想,就是經過ROW_NUMBER()爲每行生成標識。再經過BETWEEN AND 語句來獲取當前頁的數據,已達到分頁的做用。
咱們建立了一個表名TB.EXMPLE的表,添加了1,000,000條數據。咱們經過這種分頁方法來編寫以下查詢語句:
-----查看每頁顯示10條,第2頁的數據 DECLARE @PageNumber AS INT,@RowNumber AS INT SET @PageNumber=2 SET @RowNumber=5 SELETCT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ID_EXMPLE) AS NUMBER, * FROM TB_EXAMPLE )AS TBL WHERE NUMBER BETWEEN ((@PageNumber-1)*@RowNumber+1) AND (@PageNumber*@RowNumber)
結果以下:
2.OFFSET AND FETCH 分頁
offset and fetch,這是SQL SERVER 2012新添加的功能。2012如下版本,不支持。
DECALER @PageNumber AS INT,@RowNumber AS INT SET @PageNumber=2 SET @RowNumber=5 SELECT * FROM TB_EXAMPLE WHERE OFFSET ((@PageNumber-1)*@RowNumber) ROWS FETCH NEXT @RowNumber ROWS ONLY;
OFFSET A ROWS ,將前A條記錄捨去,FETCH NEXT B ROWS ,向後在讀取B條數據。
原文地址以下:http://social.technet.microsoft.com/wiki/contents/articles/23811.paging-a-query-with-sql-server.aspx.