<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介

        來源:懂視網 責編:小采 時間:2020-11-09 08:42:33
        文檔

        Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介

        Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介:排名函數是Sql Server2005新增的功能,下面簡單介紹一下他們各自的用法和區別。我們新建一張Order表并添加一些初始數據方便我們查看效果。 表結構和初始數據Sql附上表結構和初始數據圖: 一、ROW_NUMBER row_number的用途的非常廣泛,排序最好用他,一般
        推薦度:
        導讀Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介:排名函數是Sql Server2005新增的功能,下面簡單介紹一下他們各自的用法和區別。我們新建一張Order表并添加一些初始數據方便我們查看效果。 表結構和初始數據Sql附上表結構和初始數據圖: 一、ROW_NUMBER row_number的用途的非常廣泛,排序最好用他,一般

        排名函數是Sql Server2005新增的功能,下面簡單介紹一下他們各自的用法和區別。我們新建一張Order表并添加一些初始數據方便我們查看效果。

        表結構和初始數據Sql

        附上表結構和初始數據圖:

          表結構和初始數據-曉菜鳥

        一、ROW_NUMBER

          row_number的用途的非常廣泛,排序最好用他,一般可以用來實現web程序的分頁,他會為查詢出來的每一行記錄生成一個序號,依次排序且不會重復,注意使用row_number函數時必須要用over子句選擇對某一列進行排序才能生成序號。row_number用法實例:

        select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order]

          查詢結果如下圖所示:

          row_number查詢結果-曉菜鳥

          圖中的row_num列就是row_number函數生成的序號列,其基本原理是先使用over子句中的排序語句對記錄進行排序,然后按照這個順序生成序號。over子句中的order by子句與SQL語句中的order by子句沒有任何關系,這兩處的order by 可以完全不同,如以下sql,over子句中根據SubTime降序排列,Sql語句中則按TotalPrice降序排列。

        select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order] order by [TotalPrice] desc

          查詢結果如下圖所示:

          over子句和sql語句中的order by 可完全不同-曉菜鳥

          利用row_number可以實現web程序的分頁,我們來查詢指定范圍的表數據。例:根據訂單提交時間倒序排列獲取第三至第五條數據。

        with orderSection as( select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [SubTime] desc

          查詢結果如下圖所示:

          利用row_number實現分頁-曉菜鳥

          注意:在使用row_number實現分頁時需要特別注意一點,over子句中的order by 要與Sql排序記錄中的order by 保持一致,否則得到的序號可能不是連續的。下面我們寫一個例子來證實這一點,將上面Sql語句中的排序字段由SubTime改為TotalPrice。另外提一下,對于帶有子查詢和CTE的查詢,子查詢和CTE查詢有序并不代表整個查詢有序,除非顯示指定了order by。

        with orderSection as( select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [TotalPrice] desc

          查詢結果如下圖所示:

          over子句中的order by 與sql排序的order by 不一致-曉菜鳥

          

        二、RANK

          rank函數用于返回結果集的分區內每行的排名, 行的排名是相關行之前的排名數加一。簡單來說rank函數就是對查詢出來的記錄進行排名,與row_number函數不同的是,rank函數考慮到了over子句中排序字段值相同的情況,如果使用rank函數來生成序號,over子句中排序字段值相同的序號是一樣的,后面字段值不相同的序號將跳過相同的排名號排下一個,也就是相關行之前的排名數加一,可以理解為根據當前的記錄數生成序號,后面的記錄依此類推。可能我描述的比較蒼白,理解起來也比較吃力,我們直接上代碼,rank函數的使用方法與row_number函數完全相同。

        select RANK() OVER(order by [UserId]) as rank,* from [Order]

          查詢結果如下圖所示:

          使用rank函數排名-曉菜鳥

          由上圖可以看出,rank函數在進行排名時,同一組的序號是一樣的,而后面的則是根據當前的記錄數依次類推,圖中第一、二條記錄的用戶Id相同,所以他們的序號是一樣的,第三條記錄的序號則是3。  

        三、DENSE_RANK

          dense_rank函數的功能與rank函數類似,dense_rank函數在生成序號時是連續的,而rank函數生成的序號有可能不連續。dense_rank函數出現相同排名時,將不跳過相同排名號,rank值緊接上一次的rank值。在各個分組內,rank()是跳躍排序,有兩個第一名時接下來就是第四名,dense_rank()是連續排序,有兩個第一名時仍然跟著第二名。將上面的Sql語句改由dense_rank函數來實現。

        select DENSE_RANK() OVER(order by [UserId]) as den_rank,* from [Order]

          查詢結果如下圖所示:

          使用dense_rank函數排名-曉菜鳥

          圖中第一、二條記錄的用戶Id相同,所以他們的序號是一樣的,第三條記錄的序號緊接上一個的序號,所以為2不為3,后面的依此類推。

        四、NTILE

          ntile函數可以對序號進行分組處理,將有序分區中的行分發到指定數目的組中。 各個組有編號,編號從一開始。 對于每一個行,ntile 將返回此行所屬的組的編號。這就相當于將查詢出來的記錄集放到指定長度的數組中,每一個數組元素存放一定數量的記錄。ntile函數為每條記錄生成的序號就是這條記錄所有的數組元素的索引(從1開始)。也可以將每一個分配記錄的數組元素稱為“桶”。ntile函數有一個參數,用來指定桶數。下面的SQL語句使用ntile函數對Order表進行了裝桶處理:

        select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]

          查詢結果如下圖所示:

          使用ntile排名函數-曉菜鳥

          Order表的總記錄數是6條,而上面的Sql語句ntile函數指定的組數是4,那么Sql Server2005是怎么來決定每一組應該分多少條記錄呢?這里我們就需要了解ntile函數的分組依據(約定)。

          ntile函數的分組依據(約定):

          1、每組的記錄數不能大于它上一組的記錄數,即編號小的桶放的記錄數不能小于編號大的桶。也就是說,第1組中的記錄數只能大于等于第2組及以后各組中的記錄數。

          2、所有組中的記錄數要么都相同,要么從某一個記錄較少的組(命名為X)開始后面所有組的記錄數都與該組(X組)的記錄數相同。也就是說,如果有個組,前三組的記錄數都是9,而第四組的記錄數是8,那么第五組和第六組的記錄數也必須是8。

          這里對約定2進行詳細說明一下,以便于更好的理解。

          首先系統會去檢查能不能對所有滿足條件的記錄進行平均分組,若能則直接平均分配就完成分組了;若不能,則會先分出一個組,這個組分多少條記錄呢?就是 (總記錄數/總組數)+1 條,之所以分配 (總記錄數/總組數)+1 條是因為當不能進行平均分組時,總記錄數%總組數肯定是有余的,又因為分組約定1,所以先分出去的組需要+1條。

          分完之后系統會繼續去比較余下的記錄數和未分配的組數能不能進行平均分配,若能,則平均分配余下的記錄;若不能,則再分出去一組,這個組的記錄數也是(總記錄數/總組數)+1條。

          然后系統繼續去比較余下的記錄數和未分配的組數能不能進行平均分配,若能,則平均分配余下的記錄;若還是不能,則再分配出去一組,繼續比較余下的......這樣一直進行下去,直至分組完成。

          舉個例子,將51條記錄分配成5組,51%5==1不能平均分配,則先分出去一組(51/5)+1=11條記錄,然后比較余下的 51-11=40 條記錄能否平均分配給未分配的4組,能平均分配,則剩下的4組,每組各40/4=10 條記錄,分配完成,分配結果為:11,10,10,10,10,曉菜鳥我開始就錯誤的以為他會分配成 11,11,11,11,7。

          根據上面的兩個約定,可以得出如下的算法:

        //mod表示取余,p表示取整.if(記錄總數 mod 桶數==0)
        {
          recordCount=記錄總數 p 桶數;
          //將每桶的記錄數都設為recordCount.}else{
          recordCount1=記錄總數 p 桶數+1;
          int n=1;//n表示桶中記錄數為recordCount1的最大桶數.  m=recordCount1*n;  while(((記錄總數-m) mod (桶數- n)) !=0)
          {
            n++;
            m=recordCount1*n;
          }
          recordCount2=(記錄總數-m) p (桶數-n);
          //將前n個桶的記錄數設為recordCount1.  //將n+1個至后面所有桶的記錄數設為recordCount2.}

        NTILE()函數算法實現代碼

          

          根據上面的算法,如果總記錄數為59,總組數為5,則 n=4 , recordCount1=12 , recordCount2=11,分組結果為 :12,12,12,12,11。

          如果總記錄數為53,總組數為5,則 n=3 , recordCount1=11 , recordCount2=10,分組結果為:11,11,11,10,10。

          就拿上面的例子來說,總記錄數為6,總組數為4,通過算法得到 n=2 , recordCount1=2 , recordCount2=1,分組結果為:2,2,1,1。

        select ntile,COUNT([ID]) recordCount from ( select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]) as tgroup by t.ntile

          運行Sql,分組結果如圖:

          使用ntilt()函數分組-曉菜鳥

          比對算法與Sql Server的分組結果是一致的,說明算法沒錯。:)

        總結:

        在使用排名函數的時候需要注意以下三點:

          1、排名函數必須有 OVER 子句。

          2、排名函數必須有包含 ORDER BY 的 OVER 子句。

          3、分組內從1開始排序。

        本文講解了Sql 四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)相關知識,更多相關內容請關注Gxl網。

        相關推薦:

        Mysql常用基準測試工具

        Mysql函數 的相關講解

        SQLLite相關內容

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介

        Sql四大排名函數(ROW_NUMBER、RANK、DENSE_RANK、NTILE)簡介:排名函數是Sql Server2005新增的功能,下面簡單介紹一下他們各自的用法和區別。我們新建一張Order表并添加一些初始數據方便我們查看效果。 表結構和初始數據Sql附上表結構和初始數據圖: 一、ROW_NUMBER row_number的用途的非常廣泛,排序最好用他,一般
        推薦度:
        標簽: sql 排序 rank
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top 主站蜘蛛池模板: 日韩免费人妻AV无码专区蜜桃 | 一个人看的www免费在线视频| 成人免费看片又大又黄| 91亚洲性爱在线视频| 亚洲免费闲人蜜桃| 亚洲人成网站日本片| 毛片免费观看视频| 亚洲人片在线观看天堂无码| 国产一精品一AV一免费孕妇 | 国产成人精品曰本亚洲79ren| 免费在线观看亚洲| 亚洲国产中文字幕在线观看| jizz日本免费| 伊人久久综在合线亚洲2019| 成年黄网站色大免费全看| 亚洲大尺码专区影院| 四虎在线免费播放| 一道本不卡免费视频| 亚洲精品无码午夜福利中文字幕| 免费A级毛片无码A∨| 亚洲一级特黄特黄的大片| 精品无码国产污污污免费| 免费的黄色的网站| 亚洲国产成人一区二区三区| 最近免费中文字幕高清大全| 亚洲三级高清免费| 亚洲精品无码久久不卡| 久久伊人免费视频| 亚洲性色精品一区二区在线| 亚洲精品动漫人成3d在线| 精品熟女少妇a∨免费久久| 亚洲日韩精品国产一区二区三区 | 曰批免费视频播放在线看片二| 亚洲人成无码www久久久| 免费av一区二区三区| 亚洲成_人网站图片| 亚洲色偷拍另类无码专区| 日韩免费一区二区三区在线| 深夜免费在线视频| 久久久久亚洲av无码专区喷水| 日本高清免费不卡视频|