MSSQL MySQL 數(shù)據(jù)庫分頁(存儲過程)
更新時間:2012年01月09日 23:27:11 作者:
有關(guān)分頁 SQL 的資料很多,有的使用存儲過程,有的使用游標(biāo)。本人不喜歡使用游標(biāo),我覺得它耗資、效率低;使用存儲過程是個不錯的選擇,因為存儲過程是經(jīng)過預(yù)編譯的,執(zhí)行效率高,也更靈活
先看看單條 SQL 語句的分頁 SQL 吧。
方法1:
適用于 SQL Server 2000/2005
SELECT TOP 頁大小 *
FROM table1
WHERE id NOT IN
(
SELECT TOP 頁大小*(頁數(shù)-1) id FROM table1 ORDER BY id
)
ORDER BY id
方法2:
適用于 SQL Server 2000/2005
SELECT TOP 頁大小 *
FROM table1
WHERE id >
(
SELECT ISNULL(MAX(id),0)
FROM
(
SELECT TOP 頁大小*(頁數(shù)-1) id FROM table1 ORDER BY id
) A
)
ORDER BY id
方法3:
適用于 SQL Server 2005
SELECT TOP 頁大小 *
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 頁大小*(頁數(shù)-1)
方法4:
適用于 SQL Server 2005
row_number() 必須制定 order by ,不指定可以如下實現(xiàn),但不能保證分頁結(jié)果正確性,因為排序不一定可靠??赡艿谝淮尾樵冇涗汚在第一頁,第二次查詢又跑到了第二頁。
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 <=@PageNo*@pageSize
還有一種方法就是將排序字段作為變量,通過動態(tài)SQL 實現(xiàn),可以改成存儲過程。
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 '+@OrderColumns+' ) rn,* from ' +@TableName+')tb where rn >'+convert(varchar(50),(@PageNo-1)*@pageSize) +' and rn <= '+convert(varchar(50),@PageNo*@pageSize)
print @SQL
exec(@SQL)
方法5:(利用SQL的游標(biāo)存儲過程分頁)
適用于 SQL Server 2005
create procedure SqlPager
@sqlstr nvarchar(4000), --查詢字符串
@currentpage int, --第N頁
@pagesize int --每頁行數(shù)
as
set nocount on
declare @P1 int, --P1是游標(biāo)的id
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
select ceiling(1.0*@rowcount/@pagesize) as 總頁數(shù)--,@rowcount as 總行數(shù),@currentpage as 當(dāng)前頁
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中l(wèi)imit的用法詳解[數(shù)據(jù)分頁常用]
在我們使用查詢語句的時候,經(jīng)常要返回前幾條或者中間某幾行數(shù)據(jù),這個時候怎么辦呢?不用擔(dān)心,mysql已經(jīng)為我們提供了這樣一個功能。
select * from table limit [offset,] rows | rows offset offset
limit 子句可以被用于強制 select 語句返回指定的記錄數(shù)。limit 接受一個或兩個數(shù)字參數(shù)。參數(shù)必須是一個整數(shù)常量。如果給定兩個參數(shù),第一個參數(shù)指定第一個返回記錄行的偏移量,第二個參數(shù)指定返回記錄行的最大數(shù)目。初 始記錄行的偏移量是 0(而不是 1): 為了與 postgresql 兼容,mysql 也支持句法: limit # offset #。
mysql> select * from table limit 5,10; // 檢索記錄行 6-15
//為了檢索從某一個偏移量到記錄集的結(jié)束所有的記錄行,可以指定第二個參數(shù)為 -1:
mysql> select * from table limit 95,-1; // 檢索記錄行 96-last.
//如果只給定一個參數(shù),它表示返回最大的記錄行數(shù)目:
mysql> select * from table limit 5; //檢索前 5 個記錄行
//換句話說,limit n 等價于 limit 0,n。
1. select * from tablename <條件語句> limit 100,15
從100條記錄后開始取15條 (實際取取的是第101-115條數(shù)據(jù))
2. select * from tablename <條件語句> limit 100,-1
從第100條后開始-最后一條的記錄
3. select * from tablename <條件語句> limit 15
相當(dāng)于limit 0,15 .查詢結(jié)果取前15條數(shù)據(jù)
說明,頁大?。好宽摰男袛?shù);頁數(shù):第幾頁。使用時,請把"頁大小"和"頁大小*(頁數(shù)-1)"替換成數(shù)字。
其它的方案:如果沒有主鍵,可以用臨時表,也可以用方案三做,但是效率會低。
建議優(yōu)化的時候,加上主鍵和索引,查詢效率會提高。
通過SQL 查詢分析器,顯示比較:我的結(jié)論是:
分頁方案二:(利用ID大于多少和SELECT TOP分頁)效率最高,需要拼接SQL語句
分頁方案一:(利用Not In和SELECT TOP分頁) 效率次之,需要拼接SQL語句
分頁方案三:(利用SQL的游標(biāo)存儲過程分頁) 效率最差,但是最為通用
方法1:
適用于 SQL Server 2000/2005
復(fù)制代碼 代碼如下:
SELECT TOP 頁大小 *
FROM table1
WHERE id NOT IN
(
SELECT TOP 頁大小*(頁數(shù)-1) id FROM table1 ORDER BY id
)
ORDER BY id
方法2:
適用于 SQL Server 2000/2005
復(fù)制代碼 代碼如下:
SELECT TOP 頁大小 *
FROM table1
WHERE id >
(
SELECT ISNULL(MAX(id),0)
FROM
(
SELECT TOP 頁大小*(頁數(shù)-1) id FROM table1 ORDER BY id
) A
)
ORDER BY id
方法3:
適用于 SQL Server 2005
復(fù)制代碼 代碼如下:
SELECT TOP 頁大小 *
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 頁大小*(頁數(shù)-1)
方法4:
適用于 SQL Server 2005
復(fù)制代碼 代碼如下:
row_number() 必須制定 order by ,不指定可以如下實現(xiàn),但不能保證分頁結(jié)果正確性,因為排序不一定可靠??赡艿谝淮尾樵冇涗汚在第一頁,第二次查詢又跑到了第二頁。
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 <=@PageNo*@pageSize
還有一種方法就是將排序字段作為變量,通過動態(tài)SQL 實現(xiàn),可以改成存儲過程。
復(fù)制代碼 代碼如下:
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 '+@OrderColumns+' ) rn,* from ' +@TableName+')tb where rn >'+convert(varchar(50),(@PageNo-1)*@pageSize) +' and rn <= '+convert(varchar(50),@PageNo*@pageSize)
print @SQL
exec(@SQL)
方法5:(利用SQL的游標(biāo)存儲過程分頁)
適用于 SQL Server 2005
復(fù)制代碼 代碼如下:
create procedure SqlPager
@sqlstr nvarchar(4000), --查詢字符串
@currentpage int, --第N頁
@pagesize int --每頁行數(shù)
as
set nocount on
declare @P1 int, --P1是游標(biāo)的id
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
select ceiling(1.0*@rowcount/@pagesize) as 總頁數(shù)--,@rowcount as 總行數(shù),@currentpage as 當(dāng)前頁
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中l(wèi)imit的用法詳解[數(shù)據(jù)分頁常用]
在我們使用查詢語句的時候,經(jīng)常要返回前幾條或者中間某幾行數(shù)據(jù),這個時候怎么辦呢?不用擔(dān)心,mysql已經(jīng)為我們提供了這樣一個功能。
復(fù)制代碼 代碼如下:
select * from table limit [offset,] rows | rows offset offset
limit 子句可以被用于強制 select 語句返回指定的記錄數(shù)。limit 接受一個或兩個數(shù)字參數(shù)。參數(shù)必須是一個整數(shù)常量。如果給定兩個參數(shù),第一個參數(shù)指定第一個返回記錄行的偏移量,第二個參數(shù)指定返回記錄行的最大數(shù)目。初 始記錄行的偏移量是 0(而不是 1): 為了與 postgresql 兼容,mysql 也支持句法: limit # offset #。
mysql> select * from table limit 5,10; // 檢索記錄行 6-15
//為了檢索從某一個偏移量到記錄集的結(jié)束所有的記錄行,可以指定第二個參數(shù)為 -1:
mysql> select * from table limit 95,-1; // 檢索記錄行 96-last.
//如果只給定一個參數(shù),它表示返回最大的記錄行數(shù)目:
mysql> select * from table limit 5; //檢索前 5 個記錄行
//換句話說,limit n 等價于 limit 0,n。
1. select * from tablename <條件語句> limit 100,15
從100條記錄后開始取15條 (實際取取的是第101-115條數(shù)據(jù))
2. select * from tablename <條件語句> limit 100,-1
從第100條后開始-最后一條的記錄
3. select * from tablename <條件語句> limit 15
相當(dāng)于limit 0,15 .查詢結(jié)果取前15條數(shù)據(jù)
說明,頁大?。好宽摰男袛?shù);頁數(shù):第幾頁。使用時,請把"頁大小"和"頁大小*(頁數(shù)-1)"替換成數(shù)字。
其它的方案:如果沒有主鍵,可以用臨時表,也可以用方案三做,但是效率會低。
建議優(yōu)化的時候,加上主鍵和索引,查詢效率會提高。
通過SQL 查詢分析器,顯示比較:我的結(jié)論是:
分頁方案二:(利用ID大于多少和SELECT TOP分頁)效率最高,需要拼接SQL語句
分頁方案一:(利用Not In和SELECT TOP分頁) 效率次之,需要拼接SQL語句
分頁方案三:(利用SQL的游標(biāo)存儲過程分頁) 效率最差,但是最為通用
相關(guān)文章
SQL Server導(dǎo)入、導(dǎo)出、備份數(shù)據(jù)方法
注意包括導(dǎo)出導(dǎo)入SQL Server里某個數(shù)據(jù)庫,導(dǎo)出導(dǎo)入SQL Server里某個表2008-12-12Sql Server 壓縮數(shù)據(jù)庫日志文件的方法
Sql Server 日志 _log.ldf文件太大,數(shù)據(jù)庫文件有500g,日志文件也達到了500g,占用磁盤空間過大,且可能影響程序性能,需要壓縮日志文件,下面小編給大家講解下Sql Server 壓縮數(shù)據(jù)庫日志文件的方法,感興趣的朋友一起看看吧2022-11-11SQL刪除語句DROP、TRUNCATE、 DELETE 的區(qū)別
這篇文章主要介紹了SQL刪除語句DROP、TRUNCATE、 DELETE 的區(qū)別,幫助大家更好的理解和學(xué)習(xí)sql語句,感興趣的朋友可以了解下2020-09-09什么是數(shù)據(jù)庫 SQL Execution Plan(簡單介紹)
SQL Execution PlanSQL 執(zhí)行計劃是數(shù)據(jù)庫管理系統(tǒng)在執(zhí)行SQL語句時,對如何高效檢索數(shù)據(jù)進行的一系列優(yōu)化步驟的描述,這篇文章主要介紹了什么是數(shù)據(jù)庫 SQL Execution Plan,需要的朋友可以參考下2024-03-03sql server數(shù)據(jù)庫中raiserror函數(shù)用法的詳細介紹
這篇文章主要介紹了sql server數(shù)據(jù)庫中raiserror函數(shù)用法的詳細介紹,raiserror用于拋出一個異?;蝈e誤,讓這個錯誤可以被程序捕捉到。對此感興趣的可以了解一下2020-07-07在安裝了Sql2000的基礎(chǔ)上安裝Sql2005的詳細過程 圖文
在安裝了Sql2000的基礎(chǔ)上安裝Sql2005的詳細過程 圖文方法,需要的朋友可以參考下。2011-03-03