SQL SERVER 分頁方法

    最近項目中須要在SQL SERVER中進行分頁,須要編寫分頁查詢語句。以前也寫過一些關於分頁查詢的語句,可是性能不敢恭維。因而在業務時間,在微軟社區Bing了一篇老外寫的關於SQL SERVER分頁的文章。看過以後,感受本身以前寫的語句,過低端,太不科學了。  文章中講了兩種分頁方法,其中一種只適用於SQL SERVER2012以上版本。sql

  ROW_NUMBER()函數分頁express

 先介紹一下ROW_NUMBER()函數,這個函數的主要做用,從它的命名中就可看出來。ROW,每列,NUMBER數字,它的做用就是爲每行分配一個數字。可是它通常不單獨使用。它的語法是這樣的:函數

image

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

image

這個語句把表中TerritoryName不爲空、SalesYID不爲空的數據按字段SalesYTD降序排序,再經過ROW_NUMBER()函數爲每行分配一個連續的數字,將數字存入新添加的一個名爲Row的字段中。結果以下:3d

image

2.這種狀況,就是咱們今天要講的分頁方法。(Returning a subset of rows)code

image

在這個場景中,咱們用到了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

image

在這個場景中,咱們用到了PARTITION參數。咱們按區域(territoryName)將查詢結果進行分區,再在分過區的數據集中以SalesYTD降序,再爲降序後的每行數據分配數字。最後以TerritoryName字段升序。結果以下圖:

image

關於ROW_NUMBER()的原文地址:http://msdn.microsoft.com/en-us/library/ms186734.aspx.

這種分頁方法的主要思想,就是經過ROW_NUMBER()爲每行生成標識。再經過BETWEEN  AND 語句來獲取當前頁的數據,已達到分頁的做用。

image

  咱們建立了一個表名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)

結果以下:

image

 

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.

相關文章
相關標籤/搜索