<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
資料分頁往往有三種常用方案。
第一種,把資料庫中存放的相關資料,全部讀入PHP/Java/C#程式碼/記憶體,再由程式碼對其進行分頁操作(速度慢,簡易性高)。
第二種,直接在資料庫中對相關資料進行分頁操作,再把分頁後的資料輸出給程式碼程式(速度中,簡易性中)。
第三種,先把資料庫中的相關資料全部讀入“快取”或第三方工具,再由程式碼程式對“快取”或第三方工具中的資料進行讀取+分頁操作(速度快,簡易性差)。
本文下面重點闡述上述【第二種】方案在SQL Server上的使用(其它種類資料庫由於Sql語句略有差異,所以需要調整,但方案也類似)
範例:
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY menuId) AS RowId,* FROM sys_menu ) AS r WHERE RowId BETWEEN 1 AND 10
用子查詢新增一列行號(ROW_NUMBER)RowId查詢,比較高效的查詢方式,只有在SQL Server2005或更高版本才支援。
BETWEEN 1 AND 10是指查詢第1到第10條資料(閉區間),在這裡面需要注意的是OVER的括號裡面可以寫多個排序欄位。
通用用法
--pageIndex 表示指定頁 --pageSize 表示每頁顯示的條數 SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY 排序欄位) AS RowId,* FROM 表名 ) AS r WHERE RowId BETWEEN ((pageIndex-1)*pageSize + 1) AND (pageIndex * PageSize)
範例:
--offset fetch next方式查詢,最高效的查詢方式,只有在SQL Server2012或更高版本才支援 SELECT * FROM sys_menu ORDER BY menuId offset 0 ROWS FETCH NEXT 10 ROWS ONLY
offset 是跳過多少行,
next是取接下來的多少行,
句式offset...rows fetch nect ..rows only,注意rows和末尾的only 不要寫漏掉了,並且這種方式必須要接著Order by XX 使用,不然會報錯。
通用用法
--pageIndex 表示指定頁 --pageSize 表示每頁顯示的條數 SELECT * FROM 表名 ORDER BY 排序欄位 offset ((pageIndex - 1) * pageSize) ROWS FETCH NEXT pageSize ROWS ONLY
範例:
--查詢第11-20條記錄 SELECT TOP 10 menuId, * FROM sys_menu WHERE menuId NOT IN (SELECT TOP 10 menuId FROM sys_menu)
這條語句的原理是先查詢1-10條記錄的ID,然後再查詢ID不屬於這1-10條記錄的ID,並且只需要10條記錄,因為每頁大小就是10,
這就是獲取到的第11-20條記錄,這是非常簡單的一種寫法。
另外IN語句與NOT IN語句類似,這是NOT IN的寫法,但是這種寫法資料量大的話效率太低。
通用用法
--pageIndex 表示指定頁 --pageSize 表示每頁顯示的條數 SELECT TOP pageSize menuId, * FROM sys_menu WHERE menuId NOT IN (SELECT TOP ((pageSize-1)*pageIndex) menuId FROM sys_menu)
範例:
--查詢第11-20條記錄 SELECT * FROM( SELECT TOP 10 * FROM( SELECT TOP 20 * FROM sys_menu ORDER BY menuId ASC) AS TEMP1 ORDER BY menuId DESC) AS TEMP2 ORDER BY menuId ASC
這條語句首先查詢前20條記錄,然後在倒序查詢前10條記錄(即倒數10條記錄),
這個時候就已經獲取到了11-20條記錄,但是他們的順序是倒序,所以最後又進行升序排序。
通用方法
--pageIndex 表示指定頁 --pageSize 表示每頁顯示的條數 SELECT * FROM( SELECT TOP pageSize * FROM( SELECT TOP ((pageIndex - 1) * pageSize +(pageSize*2)) * FROM sys_menu ORDER BY menuId ASC) AS TEMP1 ORDER BY menuId DESC) AS TEMP2 ORDER BY menuId ASC
範例:
--查詢第11-20條記錄 SELECT TOP 10 * FROM sys_menu WHERE menuId> (SELECT MAX(menuId) FROM(SELECT TOP 10 menuId FROM sys_menu ORDER BY menuId) AS TEMP1) --(第10條的id)
這個理解起來也簡單,先把第10條記錄的id找出來(當然這裡面是直接使用MAX()進行查詢,MIN()函數的用法也是類似的),
然後再對比取比第10條記錄的id大的前10條記錄即為我們需要的結果。
這裡要注意開始時的邊界值調整。
通用用法
--pageIndex 表示指定頁 --pageSize 表示每頁顯示的條數 SELECT TOP pageSize * FROM sys_menu WHERE menuId> (SELECT MAX(menuId) FROM(SELECT TOP ((PageIndex-1)*PageSize) menuId FROM sys_menu ORDER BY menuId) AS TEMP1) --(第10條的id)
上述1~5方案,再配合儲存過程,你就能製造出適合你自己的“分頁”輪子,日後反覆使用。
但它們有一定自身侷限性:方案1、2、5都需要依賴一個排序Id(這個Id要麼是個排序列,要麼是個主鍵)。方案3、4則效率太低,完全不推薦。
此方案在DeveloperSharp框架中有提供(基於.Net/.Net Core/.Net Framework),方案被廣東省的多個公司/專案採用,得到了實戰驗證+穩定性。
【第一步】:從NuGet參照DeveloperSharp包。
【第二步】:建立一個用來與資料庫進行通訊的“資料來源類”(文字範例為:TestData.cs),內容如下:
using DeveloperSharp.Structure.Model; using DeveloperSharp.Framework.QueryEngine; namespace YZZ { [DataSource(DatabaseType.SQLServer, "Server=localhost;Database=Test;Uid=sa;Pwd=123")] public class TestData : DeveloperSharp.Structure.Model.DataLayer { //類中沒有任何程式碼 } }
說 明 :“資料來源類”(文字範例為:TestData.cs)必 須 繼 承 自 DeveloperSharp.Structure.Model.DataLayer 類 , 並 且 在 其 上 設 置DataSource屬 性 的 初 始 化 值 為“資料庫型別”及其“連結字串”。
【第三步】:新增通過“資料來源類”(TestData)呼叫其PagePartition方法進行資料分頁的程式碼。注 意:核心程式碼就一行而已!!
程式碼如下:
using DeveloperSharp.Extension;//Table擴充套件所在的名稱空間 ----------------------------- class Program { static void Main(string[] args) { TestData td = new TestData(); //分頁 var pp = td.PagePartition("select top 5000 * from t_Order where Id>10 order by Id desc", 20, 162); List<Product> Products = pp.Table.ToList<Product>(); foreach (var P in Products) { Console.WriteLine(P.Name); } Console.ReadLine(); } }
Product類程式碼如下:
public class Product { public string Id { get; set; } public string Name { get; set; } public int Quantity { get; set; } }
此處的PagePartition方法有兩個過載方法,其詳細功能說明如下:
PagePartition 宣告:public PagePiece PagePartition(string RecordSet, string Id, int PageSize, int PageIndex) 用途:分頁功能(有主鍵) 引數:(1)string RecordSet --需要分頁的記錄集,可以是表、檢視、或者SQL語句 (2)string Id --主鍵 (3)int PageSize --頁面大小 (4)int PageIndex --當前頁碼 返回:PagePiece --頁片實體 PagePartition 宣告:public PagePiece PagePartition(string RecordSet, int PageSize, int PageIndex) 用途:分頁功能(無主鍵) 引數:(1)string RecordSet -- 需要分頁的記錄集,可以是表、檢視、或者SQL語句 (2)int PageSize --頁面大小 (3)int PageIndex --當前頁碼 返回:PagePiece --頁片實體
注意:
(1) 當你需要分頁的資料表有“主鍵”欄位時,使用“分頁功能(有主鍵)”。反之,使用“分頁功能(無主鍵)”。
(2) RecordSet是你需要分頁的“資料總集”的SQL語句。該SQL語句的形式豐富多樣,可以帶條件、排序、甚至還能是多表的聯合查詢、等。
(3) 此方法符合最開始的【第二種】方案,是在SQL Server內部進行的分頁操作。而且可以不依賴於排序/排序Id。
以上內容到此結束,下面介紹下Sql Server常見的幾種分頁方式
⒈offset fetch next方式【SqlServer2012及以上版本支援】【推薦】
select * from T_User order by id offset 5 rows /*(頁數-1) * 條數 */ fetch next 5 rows only /* 條數 */
⒉row_number() over()方式【SqlServer2005以上版本支援】
select * from (select *,row_number() over(order by id) as orderId from T_User) as t where t.orderId between 11 and 15 /* (頁數-1)* 條數 + 1 */ /* 頁數 * 條數 */
⒊top not in方式【適用於SqlServer2012以下版本】
select top 5 * from T_User where id not in (select top 10 id from T_User) /* top 條數 */ /* top 條數 * 頁數 */
⒋max(主鍵)方式【本質上還是top方式,適用於SqlServer2012以下版本】
select top 5 * from T_User where id>= (select max(id) from (select top 6 id from T_User order by id asc) a) order by id; /*top 條數*/ /*top(頁數-1)* 條數 + 1*/
分析:在資料量較大時
top not in方式:查詢靠前的資料速度較快
ROW_NUMBER() OVER()方式:查詢靠後的資料速度比上一種較快
offset fetch next方式:速度穩定,優於前2種,但sql版本限制2012及以上才可使用
到此這篇關於SQL Server下7種“資料分頁”方案,全網最全的文章就介紹到這了,更多相關SQL Server資料分頁內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45