天天看點

mysql資料庫怎麼分頁代碼_MSSQL / MySQL 資料庫分頁代碼

有關分頁 SQL 的資料很多,有的使用存儲過程,有的使用遊标。本人不喜歡使用遊标,我覺得它耗資、效率低;使用存儲過程是個不錯的選擇,因為存儲過程是經過預編譯的,執行效率高,也更靈活。先看看單條 SQL 語句的分頁 SQL 吧。

方法1:

适用于 SQL Server 2000/2005

SELECTTOP頁大小*FROMtable1WHEREidNOTIN(SELECTTOP頁大小*(頁數-1) idFROMtable1ORDERBYid

)ORDERBYid

方法2:

适用于 SQL Server 2000/2005

SELECTTOP頁大小*FROMtable1WHEREid>(SELECTISNULL(MAX(id),0)FROM(SELECTTOP頁大小*(頁數-1) idFROMtable1ORDERBYid

)A

)ORDERBYid

方法3:

适用于 SQL Server 2005

SELECTTOP頁大小*FROM(SELECTROW_NUMBER()OVER(ORDERBYid)ASRowNumber,*FROMtable1

) AWHERERowNumber>頁大小*(頁數-1)

方法4:

适用于 SQL Server 2005

row_number() 必須制定 order by ,不指定可以如下實作,但不能保證分頁結果正确性,因為排序不一定可靠。可能第一次查詢記錄A在第一頁,第二次查詢又跑到了第二頁。

declare @PageNo int ,@pageSize int;

set @PageNo = 2

set @pageSize=20

select * from (

select row_number() over(order by getdate()) rn,* from sys.objects)

tb where rn >(@PageNo-1)*@pageSize and rn <[email protected]*@pageSize

還有一種方法就是将排序字段作為變量,通過動态SQL 實作,可以改成存儲過程。

declare @PageNo int ,@pageSize int;

declare @TableName varchar(128),@OrderColumns varchar(500), @SQL varchar(max);

set @PageNo = 2

set @pageSize=20

set @TableName = 'sys.objects'

set @OrderColumns = 'name ASC,object_id DESC'

set @SQL = 'select * from (

select row_number() over(order by '[email protected]+' ) rn,* from ' [email protected]+')tb where rn >'+convert(varchar(50),(@PageNo-1)*@pageSize) +' and rn <= '+convert(varchar(50),@PageNo*@pageSize)

print @SQL

exec(@SQL)

方法5:(利用SQL的遊标存儲過程分頁)

适用于 SQL Server 2005

create procedure SqlPager

@sqlstr nvarchar(4000), --查詢字元串

@currentpage int, --第N頁

@pagesize int --每頁行數

as

set nocount on

declare @P1 int, --P1是遊标的id

@rowcount int

exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@[email protected] output

select ceiling(1.0*@rowcount/@pagesize) as 總頁數--,@rowcount as 總行數,@currentpage as 目前頁

set @currentpage=(@currentpage-1)*@pagesize+1

exec sp_cursorfetch @P1,16,@currentpage,@pagesize

exec sp_cursorclose @P1

set nocount off

方法5:(利用MySQL的limit)

适用于 MySQL

mysql中limit的用法詳解[資料分頁常用]

在我們使用查詢語句的時候,經常要傳回前幾條或者中間某幾行資料,這個時候怎麼辦呢?不用擔心,mysql已經為我們提供了這樣一個功能。

select * from table limit [offset,] rows | rows offset offset

limit 子句可以被用于強制 select 語句傳回指定的記錄數。limit 接受一個或兩個數字參數。參數必須是一個整數常量。如果給定兩個參數,第一個參數指定第一個傳回記錄行的偏移量,第二個參數指定傳回記錄行的最大數目。初 始記錄行的偏移量是 0(而不是 1): 為了與 postgresql 相容,mysql 也支援句法: limit # offset #。

mysql> select * from table limit 5,10; // 檢索記錄行 6-15

//為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個參數為 -1:

mysql> select * from table limit 95,-1; // 檢索記錄行 96-last.

//如果隻給定一個參數,它表示傳回最大的記錄行數目:

mysql> select * from table limit 5; //檢索前 5 個記錄行

//換句話說,limit n 等價于 limit 0,n。

1. select * from tablename limit 100,15

從100條記錄後開始取15條 (實際取取的是第101-115條資料)

2. select * from tablename limit 100,-1

從第100條後開始-最後一條的記錄

3. select * from tablename limit 15

相當于limit 0,15 .查詢結果取前15條資料

說明,頁大小:每頁的行數;頁數:第幾頁。使用時,請把"頁大小"和"頁大小*(頁數-1)"替換成數字。

其它的方案:如果沒有主鍵,可以用臨時表,也可以用方案三做,但是效率會低。

建議優化的時候,加上主鍵和索引,查詢效率會提高。

通過SQL 查詢分析器,顯示比較:我的結論是:

分頁方案二:(利用ID大于多少和SELECT TOP分頁)效率最高,需要拼接SQL語句

分頁方案一:(利用Not In和SELECT TOP分頁) 效率次之,需要拼接SQL語句

分頁方案三:(利用SQL的遊标存儲過程分頁) 效率最差,但是最為通用