SQL分頁的幾種方法
方法一 使用offt fetch next(2012版本及以上版本才可以使用)
方法二 使用row_number()函數
利用row_number() over(order by id desc)函數計算出行數,選定相應的行數返回即可(2005版本以上才可以使用)
使用存儲過程封裝
幾種常見SQL分頁方式
createtablepagetest
(
idintidentity(1,1)notnull,
col01intnull,
col02nvarchar(50)null,
col03datetimenull
)
--分頁1,notin/top
lecttop50*frompagetest
whereidnotin(lecttop9900idfrompagetestorderbyid)
orderbyid
--分頁2,notexists
lecttop50*frompagetest
wherenotexists
(lect1from(lecttop9900idfrompagetestorderbyid)awherea.id=pagetest.id)
orderbyid
--寫法3,max/top
lecttop50*frompagetest
whereid>(lectmax(id)from(lecttop9900idfrompagetestorderbyid)a)
orderbyid
--分頁4,row_number()
lecttop50*from
(lectrow_number()over(orderbyid)rownumber,*frompagetest)a
whererownumber>9900
lect*from
(lectrow_number()over(orderbyid)rownumber,*frompagetest)a
whererownumber>9900andrownumber<9951
lect*from
(lectrow_number()over(orderbyid)rownumber,*frompagetest)a
whererownumberbetween9901and9950
--分頁5,在csdn上一帖子看到的,row_number()變體,不基于已有字段產生記錄序號,先按條件篩選以及排好序,再在結果集上給一常量列用于產生記錄序號
lect*
from(
lectrow_number()over(orderbytempColumn)rownumber,*
from(lecttop9950tempColumn=0,*frompagetestwhere1=1orderbyid)a
)b
whererownumber>9900
結論:
1.max/top,ROW_NUMBER()都是比較不錯的分頁方法。相比ROW_NUMBER()只支持sql2005及以上版本,max/top有更好的可移植性,能同時適用于sql2000,access。
2.not exists感覺是要比not in效率高一點點。
3.ROW_NUMBER()的3種不同寫法效率看起來差不多。
4.ROW_NUMBER() 的變體基于這個測試效率實在不好。
如何使用sql語句進行分頁操作?
利用SQL語句分頁要看你用的什么數據庫。
Oracle數據庫可以使用ROWNUM或row_number(),例如:Select
*
from
(lect
ROWNUM
rn,
t.*
from
table
t)
where
rn
between
11
and
20;
Select
*
from
(lect
row_number()
over
(ORDER
BY
col1)
rn,
t.*
from
table
t)
where
rn
between
11
and
20;
SQLServer數據庫可以用Top或者row_number()函數,道理同上。
利用SQL分頁有局限性,就是針對不同的數據庫有不同的寫法,所以通常會在應用程序里面做分頁通用性比較強。但是對于數據量非常龐大的應用來說,還是用SQL分頁比較適合。
MySQL分頁的sql語言怎么寫?
1、首先我們建立一個表表的數據,這個表里有25條數據,id從1到25。(下圖是部分截圖)
2、要分頁數據,首先我們假設一頁有10條數據,我們可以用mysql的limit關鍵字來限定返回多少條數據。并且用orderby來排序數據,這里用id來排序。所以第一頁的sql可以如圖這樣寫。
3、執行后得到的數據如圖,就是id從1到10的前10條數據,因為我們是按id升序來排序的。
4、上面第一頁的sql是簡化的寫法,完整的寫法如圖,得到的結果和上圖的一模一樣。代碼里limit0,10的意思是從第一條數據開始,取10條數據。(注意的是第一條數據是從0開始的)
5、那么第二頁的數據,關鍵是要知道是從哪一條數據開始,可以用這個公式得到:(頁碼-1)*每頁顯示多少條,即(2-1)*10=10,所以sql語句如圖,limit10,10。
6、執行后,結果正確,得到id從11到20的10條數據。
7、同理第三頁數據的sql如圖,<br/>就是limit20,10。
8、查詢的結果如圖,因為這頁只剩下5條數據了,所以只顯示5條數據。如果你有更多頁的數據,后面的數據只需要按上面的公式,得到從哪行開始,就可以寫對應的sql語句了。
用SQL語句怎么實現數據庫分頁?
CREATE
PROC
sp_PageView
@tbname
sysname,
--要分頁顯示的表名
@FieldKey
nvarchar(1000),
--用于定位記錄的主鍵(惟一鍵)字段,可以是逗號分隔的多個字段
@PageCurrent
int=1,
--要顯示的頁碼
@PageSize
int=10,
--每頁的大小(記錄數)
@FieldShow
nvarchar(1000)='',
--以逗號分隔的要顯示的字段列表,如果不指定,則顯示所有字段
@FieldOrder
nvarchar(1000)='',
--以逗號分隔的排序字段列表,可以指定在字段后面指定DESC/ASC用于指定排序順序
@Where
nvarchar(1000)='',
--查詢條件
@PageCount
int
OUTPUT
--總頁數
AS
SET
NOCOUNT
ON
--檢查對象是否有效
IF
OBJECT_ID(@tbname)
IS
NULL
BEGIN
RAISERROR(N'對象"%s"不存在',1,16,@tbname)
RETURN
END
IF
OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0
AND
OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0
AND
OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0
BEGIN
RAISERROR(N'"%s"不是表、視圖或者表值函數',1,16,@tbname)
RETURN
END
--分頁字段檢查
IF
ISNULL(@FieldKey,N'')=''
BEGIN
RAISERROR(N'分頁處理需要主鍵(或者惟一鍵)',1,16)
RETURN
END
--其他參數檢查及規范
IF
ISNULL(@PageCurrent,0)<1
SET
@PageCurrent=1
IF
ISNULL(@PageSize,0)<1
SET
@PageSize=10
IF
ISNULL(@FieldShow,N'')=N''
SET
@FieldShow=N'*'
IF
ISNULL(@FieldOrder,N'')=N''
SET
@FieldOrder=N''
ELSE
SET
@FieldOrder=N'ORDER
BY
'+LTRIM(@FieldOrder)
IF
ISNULL(@Where,N'')=N''
SET
@Where=N''
ELSE
SET
@Where=N'WHERE
('+@Where+N')'
--如果@PageCount為NULL值,則計算總頁數(這樣設計可以只在第一次計算總頁數,以后調用時,把總頁數傳回給存儲過程,避免再次計算總頁數,對于不想計算總頁數的處理而言,可以給@PageCount賦值)
IF
@PageCount
IS
NULL
BEGIN
DECLARE
@sql
nvarchar(4000)
SET
@sql=N'SELECT
@PageCount=COUNT(*)'
+N'
FROM
'+@tbname
+N'
'+@Where
EXEC
sp_executesql
@sql,N'@PageCount
int
OUTPUT',@PageCount
OUTPUT
SET
@PageCount=(@PageCount+@PageSize-1)/@PageSize
END
--計算分頁顯示的TOPN值
DECLARE
@TopN
varchar(20),@TopN1
varchar(20)
SELECT
@TopN=@PageSize,
@TopN1=@PageCurrent*@PageSize
--第一頁直接顯示
IF
@PageCurrent=1
EXEC(N'SELECT
TOP
'+@TopN
+N'
'+@FieldShow
+N'
FROM
'+@tbname
+N'
'+@Where
+N'
'+@FieldOrder)
ELSE
BEGIN
--生成主鍵(惟一鍵)處理條件
DECLARE
@Where1
nvarchar(4000),@s
nvarchar(1000)
SELECT
@Where1=N'',@s=@FieldKey
WHILE
CHARINDEX(N',',@s)>0
SELECT
@s=STUFF(@s,1,CHARINDEX(N',',@s),N''),
@Where1=@Where1
+N'
AND
a.'+LEFT(@s,CHARINDEX(N',',@s)-1)
+N'='+LEFT(@s,CHARINDEX(N',',@s)-1)
SELECT
@Where1=STUFF(@Where1+N'
AND
a.'+@s+N'='+@s,1,5,N''),
@TopN=@TopN1-@PageSize
--執行查詢
EXEC(N'SET
ROWCOUNT
'+@TopN1
+N'
SELECT
'+@FieldKey
+N'
INTO
#
FROM
'+@tbname
+N'
'+@Where
+N'
'+@FieldOrder
+N'
SET
ROWCOUNT
'+@TopN
+N'
DELETE
FROM
#'
+N'
SELECT
'+@FieldShow
+N'
FROM
'+@tbname
+N'
a
WHERE
EXISTS(SELECT
*
FROM
#
WHERE
'+@Where1
+N')
'+@FieldOrder)
END
使用sql語句實現分頁查詢
使用sql語句在語句末尾添加 limit page,count //意思是 獲取從page+1開始的count條記錄
例如:lect * from checkmoney where phonenumber='18209183861' order by check_start_time desc limit 1,5;
這條語句獲取了 checkmoney的第 2條至第6條 記錄。